<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>函数式编程和Python新核心特性 | SanShui的个人博客</title><meta name="author" content="SanShui"><meta name="copyright" content="SanShui"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="函数式编程和Python新核心特性">
<meta property="og:type" content="article">
<meta property="og:title" content="函数式编程和Python新核心特性">
<meta property="og:url" content="https://huaiyuechusan.github.io/archives/fab44cdf.html">
<meta property="og:site_name" content="SanShui的个人博客">
<meta property="og:description" content="函数式编程和Python新核心特性">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://wallpaper.csun.site/?7">
<meta property="article:published_time" content="2024-01-14T12:24:00.000Z">
<meta property="article:modified_time" content="2024-10-17T11:57:53.429Z">
<meta property="article:author" content="SanShui">
<meta property="article:tag" content="学习技术">
<meta property="article:tag" content="Python">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://wallpaper.csun.site/?7"><link rel="shortcut icon" href="/./img/config_img/%E9%98%B3%E5%85%89%E5%B0%8F%E7%8C%AB.jpg"><link rel="canonical" href="https://huaiyuechusan.github.io/archives/fab44cdf"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":true,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"bottom-left"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '函数式编程和Python新核心特性',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-10-17 19:57:53'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"><script src="https://npm.elemecdn.com/echarts@4.9.0/dist/echarts.min.js"></script><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-double-row-display@1.00/cardlistpost.min.css"/>
<style>#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags:before {content:"\A";
  white-space: pre;}#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags > .article-meta__separator{display:none}</style>
<link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-categories-card@1.0.0/lib/categorybar.css"><link rel="stylesheet" href="/./css/runtime.css" media="print" onload="this.media='all'"><!-- hexo injector head_end end --><meta name="generator" content="Hexo 5.4.2"><link rel="alternate" href="/atom.xml" title="SanShui的个人博客" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>const preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',()=> { preloader.endLoading() })

if (true) {
  document.addEventListener('pjax:send', () => { preloader.initLoading() })
  document.addEventListener('pjax:complete', () => { preloader.endLoading() })
}</script><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/./img/config_img/%E9%98%B3%E5%85%89%E5%B0%8F%E7%8C%AB.jpg" onerror="onerror=null;src='./img/config_img/蓝天.jpg'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">25</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">16</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope-open"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('http://wallpaper.csun.site/?7')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">SanShui的个人博客</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 主页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope-open"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">函数式编程和Python新核心特性</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2024-01-14T12:24:00.000Z" title="发表于 2024-01-14 20:24:00">2024-01-14</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-10-17T11:57:53.429Z" title="更新于 2024-10-17 19:57:53">2024-10-17</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Python/">Python</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">21.3k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>87分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="函数式编程和Python新核心特性"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><meta name="referrer" content="no-referrer" />

<h1 id="函数式编程和Python新核心特性"><a href="#函数式编程和Python新核心特性" class="headerlink" title="函数式编程和Python新核心特性"></a>函数式编程和Python新核心特性</h1><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828629.png" alt="image-20240107144536048"></p>
<p>函数式编程(functional programming)其实是个很古老的概念，诞生距今快60年啦!</p>
<p>最古老的函数式编程语言Lisp</p>
<p>新出现的函数式编程语言：比如Erlang、.Scala、clojure等</p>
<p>热门语言：Python、java、JavaScript、C++等都增加了函数式编程的一些特性。</p>
<blockquote>
<p>:warning:函数式编程在某些时刻，非常方便！但不需大家二选一。</p>
<p>:warning:我们通过一些常见的函数式编程的内容，先学习，后体会“函数式编程”。</p>
</blockquote>
<h2 id="函数式编程核心-高阶函数、闭包等"><a href="#函数式编程核心-高阶函数、闭包等" class="headerlink" title="函数式编程核心(高阶函数、闭包等)"></a>函数式编程核心(高阶函数、闭包等)</h2><h3 id="高阶函数和内存分析"><a href="#高阶函数和内存分析" class="headerlink" title="高阶函数和内存分析"></a>高阶函数和内存分析</h3><h4 id="函数是一等公民"><a href="#函数是一等公民" class="headerlink" title="函数是一等公民"></a>函数是一等公民</h4><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828631.png" alt="image-20240107144947021"></p>
<p>函数式编程最鲜明的特点就是：函数是一等公民(first class)，指的是函数与其他数据类型一样，处于平等地位，可以赋值给其他变量，也可以作为参数，传入另一个函数或者作为别的函数的返回值。</p>
<p><strong>一个函数可以接收另一个函数作为参数，这种函数就称之为高阶函数。</strong></p>
<p>Python内建的高阶函数有<code>map</code>、<code>reduce</code>、<code>filter</code>、<code>sorted</code></p>
<h4 id="高阶函数-内存状态分析"><a href="#高阶函数-内存状态分析" class="headerlink" title="高阶函数_内存状态分析"></a>高阶函数_内存状态分析</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">test1</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;test function run!!!&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test3</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;test3,<span class="subst">&#123;a&#125;</span>,<span class="subst">&#123;b&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test2</span>(<span class="params">func, *args, **kwargs</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;test2 function run!!!&quot;</span>)</span><br><span class="line">    func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a = test1</span><br><span class="line">test2(a)</span><br><span class="line">test2(test3, <span class="number">10</span>, <span class="number">20</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">test2 function run!!!</span></span><br><span class="line"><span class="string">test function run!!!</span></span><br><span class="line"><span class="string">test2 function run!!!</span></span><br><span class="line"><span class="string">test3,10,20</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828632.png" alt="image-20240107150419769"></p>
<h3 id="lambda表达式和匿名函数"><a href="#lambda表达式和匿名函数" class="headerlink" title="lambda表达式和匿名函数"></a>lambda表达式和匿名函数</h3><p>详情见Python入门篇的函数和内存分析章节</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">f = <span class="keyword">lambda</span> a, b, c: a + b + c</span><br><span class="line"><span class="built_in">print</span>(f)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">id</span>(f))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(f))</span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;function &lt;lambda&gt; at 0x000001AF907F7E50&gt;</span></span><br><span class="line"><span class="string">1853555179088</span></span><br><span class="line"><span class="string">&lt;class &#x27;function&#x27;&gt;</span></span><br><span class="line"><span class="string">6</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line">g = [<span class="keyword">lambda</span> a: a * <span class="number">2</span>, <span class="keyword">lambda</span> b: b * <span class="number">4</span>, <span class="keyword">lambda</span> c: c * <span class="number">8</span>]</span><br><span class="line"><span class="built_in">print</span>(g[<span class="number">0</span>](<span class="number">1</span>), g[<span class="number">1</span>](<span class="number">2</span>), g[<span class="number">2</span>](<span class="number">3</span>))</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">2 8 24</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="偏函数"><a href="#偏函数" class="headerlink" title="偏函数"></a>偏函数</h3><p>Python的<code>functools</code>模块提供了很多有用的功能，其中一个就是偏函数(Partial function)。要注意，这里的偏函数和数学意义上的偏函数不一样。</p>
<p>偏函数：作用就是把一个函数某些<strong>参数固定住</strong>（也就是设置默认值），返回一个新的函数，调用这个新的函数会更简单。</p>
<p>举例如下：</p>
<p><code>int()</code>函数可以把字符串转换为整数，当仅传入字符串时，<code>int()</code>函数默认按十进制转换，代码如下：</p>
<p><code>print(int(&#39;12345))</code></p>
<p>但<code>int()</code>函数还提供额外的base参数，默认值为10。如果传入base参数，就可以做N进制的转换：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#base参数</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;转换为八进制&#x27;</span>，<span class="built_in">int</span>(<span class="string">&#x27;12345&#x27;</span>,base=<span class="number">8</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;转换为十六进制&#x27;</span>，<span class="built_in">int</span>(<span class="string">&#x27;12345&#x27;</span>,<span class="number">16</span>))</span><br></pre></td></tr></table></figure>
<p>假设要转换大量的二进制字符串，每次都传入<code>int(x, base=2)</code>非常麻烦，于是，我们想到，可以定义一个<code>int2()</code>的函数，默认把<code>base=2</code>传进去，现在定义一个<code>int2</code>函数，代码如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">int2</span>(<span class="params">x,base=<span class="number">2</span></span>):</span><br><span class="line">	<span class="keyword">return</span> <span class="built_in">int</span>(x,base)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(int2(<span class="string">&#x27;1000000&#x27;</span>))  <span class="comment">#64</span></span><br><span class="line"><span class="built_in">print</span>(int2(<span class="string">&#x27;1010101&#x27;</span>))  <span class="comment">#85</span></span><br></pre></td></tr></table></figure>
<p><code>functools.partial</code>就是帮助我们创建一个偏函数的，不需要我们自己定义<code>int2()</code>,可以直接使用下面的代码创建一个新的函数<code>int2</code>:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> functools</span><br><span class="line"></span><br><span class="line">int2 = functools.partial(<span class="built_in">int</span>, base=<span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(int2(<span class="string">&#x27;1000000&#x27;</span>))  <span class="comment"># 64</span></span><br><span class="line"><span class="built_in">print</span>(int2(<span class="string">&#x27;1010101&#x27;</span>))  <span class="comment"># 85</span></span><br><span class="line"><span class="built_in">print</span>(int2(<span class="string">&#x27;1000000&#x27;</span>, base=<span class="number">10</span>))  <span class="comment"># 也可以修改base的值</span></span><br></pre></td></tr></table></figure>
<h3 id="闭包closure"><a href="#闭包closure" class="headerlink" title="闭包closure"></a>闭包closure</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828633.png" alt="image-20240107152421229"></p>
<p>根据字面意思，可以形象地把闭包理解为一个封闭的包裹，这个包裹就是一个函数。当然还有函数内部对应的逻辑，包裹里面的东西就是自由变量（外部函数的局部变量），自由变量可以随着包裹到处游荡。</p>
<blockquote>
<p>局部变量：如果名称绑定再一个代码块中，则为该代码块的局部变量，除非声明为nonloca或global</p>
<p>全局变量：如果模块绑定在模块层级，则为全局变量</p>
<p>自由变章：如果变量在一个代码块中被使用但不是在其中定义，则为自由变量（不会被回收）</p>
</blockquote>
<h4 id="闭包概念和第一个闭包程序"><a href="#闭包概念和第一个闭包程序" class="headerlink" title="闭包概念和第一个闭包程序"></a>闭包概念和第一个闭包程序</h4><p>我们知道，函数作用域是独立的、封闭的，外部的执行环境是访问不了的，但是闭包具有这个能力和权限。</p>
<p>闭包是一个函数，只不过这个函数有超能力，可以访问到另一个函数的作用域。</p>
<blockquote>
<p>「函数」和「自由变量」的总和，就是一个闭包。</p>
</blockquote>
<p>闭包的特点：</p>
<p>第一，闭包是一个函数，而且存在于另一个函数当中</p>
<p>第二，闭包可以访问到父级函数的变量，且该变量不会销毁</p>
<p><strong>第三，外层函数把内层的这个函数本身当成返回值进行返回</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">闭包的特点：</span></span><br><span class="line"><span class="string">1、存在内外层函数嵌套情况</span></span><br><span class="line"><span class="string">2、内层函数引用了外层函数的变量或者参数（自由变量）</span></span><br><span class="line"><span class="string">3、外层函数把内层的这个函数本身当成返回值进行返回</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">outer</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;outer&quot;</span>)</span><br><span class="line">    a = <span class="number">1</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;inner&quot;</span>)</span><br><span class="line">        <span class="comment"># 如果要修改a的值，声明为nonlocal</span></span><br><span class="line">        <span class="keyword">nonlocal</span> a</span><br><span class="line">        <span class="comment"># 闭包是由于函数内部使用了函数外部的变量。</span></span><br><span class="line">        <span class="comment"># 这个函数对象不销毁，则外部函数的局部变量也不会被销毁。</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;a:<span class="subst">&#123;a&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">inn = outer()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;-------&quot;</span>)</span><br><span class="line">inn()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">outer</span></span><br><span class="line"><span class="string">-------</span></span><br><span class="line"><span class="string">inner</span></span><br><span class="line"><span class="string">a:1</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="闭包内存分析"><a href="#闭包内存分析" class="headerlink" title="闭包内存分析"></a>闭包内存分析</h4><ol>
<li><p>执行完<code>inn=outer()</code>的内存图。<code>outer()</code>栈帧执行完后实际已经消失了，画上去，是为了展现关系。</p>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828634.png" alt="image-20240107164118698"></p>
</li>
<li><p>执行完<code>inn=outer()</code>的内存图。由于<code>inner()</code>内部函数的调用，<code>outer()</code>栈帧消失后，局部变量a指向的对象<code>1</code>仍然存在。从而形成了”闭包”。</p>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828635.png" alt="image-20240107164533098"></p>
</li>
<li><p>第一次调用<code>inn()</code>,从而调用内部函数，仍然可以拿到以前局部变量指向的对象<code>1</code></p>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828636.png" alt="image-20240107164729573"></p>
</li>
<li><p>第二次调用<code>inn(),</code>仍然可以继续拿到以前局部变量指向的对象<code>1</code>，并将值变为<code>2</code></p>
</li>
</ol>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828637.png" alt="image-20240107164746383"></p>
<blockquote>
<p>闭包可以当成两个部分组成的整体：</p>
<ol>
<li>函数</li>
<li>自由变量</li>
</ol>
</blockquote>
<h4 id="闭包的作用"><a href="#闭包的作用" class="headerlink" title="闭包的作用"></a>闭包的作用</h4><p>作用1：隐藏变量，避免全局污染</p>
<p>作用2：可以读取函数内部的变量</p>
<p><strong>同时闭包使用不当，优点就变成了缺点：</strong></p>
<p>缺点1：导致变量不会被垃圾回收机制回收，造成内存消耗</p>
<p>缺点2：不恰当的使用闭包可能会造成内存泄漏的问题</p>
<h4 id="闭包和自由变量"><a href="#闭包和自由变量" class="headerlink" title="闭包和自由变量"></a>闭包和自由变量</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">需求：实现变量a自增</span></span><br><span class="line"><span class="string">通过自由变量，可以实现递增，也不会污染其他程序</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line">a = <span class="number">10</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>():</span><br><span class="line">    a = <span class="number">10</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">increment</span>():</span><br><span class="line">        <span class="keyword">nonlocal</span> a</span><br><span class="line">        a += <span class="number">1</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;a:&quot;</span>, a)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> increment</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_ten</span>():</span><br><span class="line">    <span class="keyword">if</span> a == <span class="number">10</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;ten!&quot;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;全局变量a不等于10&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">increment = add()</span><br><span class="line">increment()</span><br><span class="line">increment()</span><br><span class="line">print_ten()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">a: 11</span></span><br><span class="line"><span class="string">a: 12</span></span><br><span class="line"><span class="string">ten!</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="案例：用闭包实现不修改源码添加功能"><a href="#案例：用闭包实现不修改源码添加功能" class="headerlink" title="案例：用闭包实现不修改源码添加功能"></a>案例：用闭包实现不修改源码添加功能</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">本次内容是装饰器的基础</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">outfunc</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,start&quot;</span>)</span><br><span class="line">        func(*args, **kwargs)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,end&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun1</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能1&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>(<span class="params">a, b, c</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2&quot;</span>, a, b, c)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">id</span>(fun1))</span><br><span class="line">fun1 = outfunc(fun1)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">id</span>(fun1))</span><br><span class="line">fun1()</span><br><span class="line">fun2 = outfunc(fun2)</span><br><span class="line">fun2(<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">1474019303136</span></span><br><span class="line"><span class="string">1474084402656</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能1</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能2 10 20 30</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="map函数（内置函数）"><a href="#map函数（内置函数）" class="headerlink" title="map函数（内置函数）"></a>map函数（内置函数）</h3><p><code>map()</code>函数接收两种参数，==一个是函数，另一个是序列(可以传入多个序列)==，map将传入的函数依次作用到序列的每个元素，并把结果作为新的list返回。</p>
<p>比如我们有一个函数<code>f(x)=x2</code>,要把这个函数作用在一个<code>list[1,2,3,4,5,6,7,8,9]</code>上，就可以用<code>map()</code>实现如下：</p>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828638.png" alt="image-20240107172241103"></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># map高阶函数使用案例</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="keyword">return</span> x * x</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">L = <span class="built_in">map</span>(f, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[1, 4, 9, 16]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># map高阶函数使用案例（用匿名函数）</span></span><br><span class="line">L = <span class="built_in">map</span>(<span class="keyword">lambda</span> n: n * n, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[1, 4, 9, 16]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># map函数传入两个列表</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">f2</span>(<span class="params">x, y</span>):</span><br><span class="line">    <span class="keyword">return</span> x + y</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">L = <span class="built_in">map</span>(f2, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>], [<span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[7, 9, 11, 13]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># map函数传入两个列表（用匿名函数）</span></span><br><span class="line">L = <span class="built_in">map</span>(<span class="keyword">lambda</span> x, y: x + y, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>], [<span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[7, 9, 11, 13]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="reduce函数（位于functools模块）"><a href="#reduce函数（位于functools模块）" class="headerlink" title="reduce函数（位于functools模块）"></a>reduce函数（位于<code>functools</code>模块）</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828639.png" alt="image-20240107174156892"></p>
<p>reduce位于<code>functools</code>模块</p>
<p>reduce把一个函数作用在一个序列[x1,x2,x3…]上，这个函数<strong>必须接收两个参数</strong>，<strong>reduce把结果继续和序列的下一个元素做累积计算</strong>，其效果就是：<br>                        <code>reduce(f,[x1,x2,x3,x4]) = f(f(f(x1,x2),x3),x4)</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># reduce实现对一个序列求和</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> reduce</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">x, y</span>):</span><br><span class="line">    <span class="keyword">return</span> x + y</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">sum</span> = reduce(add, [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sum</span>)</span><br></pre></td></tr></table></figure>
<h3 id="filter函数（内置函数）"><a href="#filter函数（内置函数）" class="headerlink" title="filter函数（内置函数）"></a>filter函数（内置函数）</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401071828640.png" alt="image-20240107174734746"></p>
<p>内置函数<code>filter()</code>用于过滤序列。<code>filter()</code>把传入的函数依次作用于每个元素，然后根据返回值是True还是False,决定保留还是丢弃该元素。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># filter过滤列表，删除偶数，只保留奇数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">is_odd</span>(<span class="params">n</span>):</span><br><span class="line">    <span class="keyword">return</span> n % <span class="number">2</span> == <span class="number">1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">L = <span class="built_in">filter</span>(is_odd, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"></span><br><span class="line"><span class="comment"># filter过滤列表，删除偶数，只保留奇数（用匿名函数实现）</span></span><br><span class="line">L = <span class="built_in">filter</span>(<span class="keyword">lambda</span> n: n % <span class="number">2</span> == <span class="number">1</span>, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># filter序列中的空字符串删除</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">not_empty</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="comment"># strip()取出字符串首位指定信息</span></span><br><span class="line">    <span class="keyword">return</span> s <span class="keyword">and</span> s.strip()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">L = <span class="built_in">filter</span>(not_empty, [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;&quot;</span>, <span class="literal">None</span>, <span class="string">&quot; &quot;</span>, <span class="string">&quot;C&quot;</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"><span class="comment"># filter序列中的空字符串删除（用匿名函数实现）</span></span><br><span class="line">L = <span class="built_in">filter</span>(<span class="keyword">lambda</span> s: (s <span class="keyword">and</span> s.strip()), [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;&quot;</span>, <span class="literal">None</span>, <span class="string">&quot; &quot;</span>, <span class="string">&quot;C&quot;</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(L))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[1, 3, 5]</span></span><br><span class="line"><span class="string">[1, 3, 5]</span></span><br><span class="line"><span class="string">[&#x27;a&#x27;, &#x27;b&#x27;, &#x27;C&#x27;]</span></span><br><span class="line"><span class="string">[&#x27;a&#x27;, &#x27;b&#x27;, &#x27;C&#x27;]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="sorted函数（内置函数）"><a href="#sorted函数（内置函数）" class="headerlink" title="sorted函数（内置函数）"></a>sorted函数（内置函数）</h3><p>排序算法，排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序，排序的核心是比较两个元素的大小。</p>
<ol>
<li>如果是数字，我们可以直接比较</li>
<li>如果是自定义对象呢？直接比较数学上的大小是没有意义的，因此，比较的过程必须通过函数抽象出来。通常规定，对于两个元素x和y，如果认为<code>x&lt;y</code>,则返回<code>-1</code>，如果认为<code>x==y</code>，则返回<code>0</code>，如果认为<code>x&gt;y</code>，则返回<code>1</code>，这样，排序算法就不用关心具体的比较过程，而是根据比较结果直接排序。</li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># sorted对list进行排序</span></span><br><span class="line">sorted1 = <span class="built_in">sorted</span>([<span class="number">1</span>, <span class="number">23</span>, -<span class="number">2</span>, -<span class="number">20</span>, <span class="number">99</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;升序排列：&quot;</span>, <span class="built_in">list</span>(sorted1))</span><br></pre></td></tr></table></figure>
<p>sorted()函数也是一个高阶函数，它还可以接收一个key函数来实现自定义的排序</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># sorted对list进行排序</span></span><br><span class="line">sorted1 = <span class="built_in">sorted</span>([<span class="number">1</span>, <span class="number">23</span>, -<span class="number">2</span>, -<span class="number">20</span>, <span class="number">99</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;升序排序：&quot;</span>, <span class="built_in">list</span>(sorted1))</span><br><span class="line"></span><br><span class="line"><span class="comment"># sorted函数接收一个key自定义排序</span></span><br><span class="line"><span class="comment"># abs按绝对值排序</span></span><br><span class="line">sorted2 = <span class="built_in">sorted</span>([<span class="number">1</span>, <span class="number">23</span>, -<span class="number">2</span>, -<span class="number">20</span>, <span class="number">99</span>], key=<span class="built_in">abs</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;自定义排序：&quot;</span>, <span class="built_in">list</span>(sorted2))</span><br><span class="line"></span><br><span class="line">sorted3 = <span class="built_in">sorted</span>([<span class="number">1</span>, <span class="number">23</span>, -<span class="number">2</span>, -<span class="number">20</span>, <span class="number">99</span>], key=<span class="built_in">abs</span>, reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;自定义逆序排序：&quot;</span>, <span class="built_in">list</span>(sorted3))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 字符串排序按照ASCII</span></span><br><span class="line">sorted4 = <span class="built_in">sorted</span>([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;ABC&quot;</span>, <span class="string">&quot;D&quot;</span>, <span class="string">&quot;d&quot;</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;字符串排序：&quot;</span>, <span class="built_in">list</span>(sorted4))</span><br><span class="line"><span class="comment"># 忽略字符串大小写排序</span></span><br><span class="line">sorted5 = <span class="built_in">sorted</span>([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;ABC&quot;</span>, <span class="string">&quot;D&quot;</span>, <span class="string">&quot;d&quot;</span>], key=<span class="built_in">str</span>.lower)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;忽略字符串大小写排序：&quot;</span>, <span class="built_in">list</span>(sorted5))</span><br><span class="line"><span class="comment"># 忽略字符串大小写反向排序</span></span><br><span class="line">sorted6 = <span class="built_in">sorted</span>([<span class="string">&quot;abc&quot;</span>, <span class="string">&quot;ABC&quot;</span>, <span class="string">&quot;D&quot;</span>, <span class="string">&quot;d&quot;</span>], key=<span class="built_in">str</span>.lower, reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;忽略字符串大小写反向排序：&quot;</span>, <span class="built_in">list</span>(sorted6))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">升序排序： [-20, -2, 1, 23, 99]</span></span><br><span class="line"><span class="string">自定义排序： [1, -2, -20, 23, 99]</span></span><br><span class="line"><span class="string">自定义逆序排序： [99, 23, -20, -2, 1]</span></span><br><span class="line"><span class="string">字符串排序： [&#x27;ABC&#x27;, &#x27;D&#x27;, &#x27;abc&#x27;, &#x27;d&#x27;]</span></span><br><span class="line"><span class="string">忽略字符串大小写排序： [&#x27;abc&#x27;, &#x27;ABC&#x27;, &#x27;D&#x27;, &#x27;d&#x27;]</span></span><br><span class="line"><span class="string">忽略字符串大小写反向排序： [&#x27;D&#x27;, &#x27;d&#x27;, &#x27;abc&#x27;, &#x27;ABC&#x27;]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p><strong>sorted对自定义对象排序</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> cmp_to_key</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, age, name</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">custom_sorted</span>(<span class="params">stu1, stu2</span>):</span><br><span class="line">    <span class="keyword">if</span> stu1.age &lt; stu2.age:</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> stu1.age &gt; stu2.age:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">stu1 = Student(<span class="number">18</span>, <span class="string">&quot;aaa&quot;</span>)</span><br><span class="line">stu2 = Student(<span class="number">28</span>, <span class="string">&quot;bbb&quot;</span>)</span><br><span class="line">stu3 = Student(<span class="number">21</span>, <span class="string">&quot;ccc&quot;</span>)</span><br><span class="line">student_list = <span class="built_in">sorted</span>([stu1, stu2, stu3], key=<span class="keyword">lambda</span> x: x.age)</span><br><span class="line"><span class="keyword">for</span> stu <span class="keyword">in</span> student_list:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;stu.name&#125;</span>-----<span class="subst">&#123;stu.age&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line">student_list = <span class="built_in">sorted</span>([stu1, stu2, stu3], key=cmp_to_key(custom_sorted))</span><br><span class="line"><span class="keyword">for</span> stu <span class="keyword">in</span> student_list:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;cmp_to_key排序：<span class="subst">&#123;stu.name&#125;</span>-----<span class="subst">&#123;stu.age&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">aaa-----18</span></span><br><span class="line"><span class="string">ccc-----21</span></span><br><span class="line"><span class="string">bbb-----28</span></span><br><span class="line"><span class="string">cmp_to_key排序：aaa-----18</span></span><br><span class="line"><span class="string">cmp_to_key排序：ccc-----21</span></span><br><span class="line"><span class="string">cmp_to_key排序：bbb-----28</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h2 id="装饰器深入剖析"><a href="#装饰器深入剖析" class="headerlink" title="装饰器深入剖析"></a>装饰器深入剖析</h2><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191857328.png" alt="image-20240107183115735"></p>
<h3 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h3><p>装饰器来自 <code>Decorator</code> 的直译。什么叫装饰，就是装点、提供一些额外的功能。在 Python 中的装饰器则是提供了一些额外的功能。</p>
<p>装饰器本质上是一个Python函数（其实就是<strong>闭包</strong>），它可以让其他函数在==不需要做任何代码变动的前提下增加额外功能==，装饰器的返回值也是一个函数对象。</p>
<p>装饰器用于有以下场景，比如：插入日志、性能测试、事务处理、缓存、权限校验等场景。</p>
<h3 id="装饰器解决日志问题"><a href="#装饰器解决日志问题" class="headerlink" title="装饰器解决日志问题"></a>装饰器解决日志问题</h3><p>闭包解决日志问题</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mylog</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,start&quot;</span>)</span><br><span class="line">        func(*args, **kwargs)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,end&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun1</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能1&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>(<span class="params">a, b, c</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2&quot;</span>, a, b, c)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">fun1 = mylog(fun1)</span><br><span class="line">fun2 = mylog(fun2)</span><br><span class="line"></span><br><span class="line">fun1()</span><br><span class="line">fun2(<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能1</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能2 10 20 30</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>装饰器解决日志问题（增加参数处理，可以装饰任意多个参数的函数）</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mylog</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,start&quot;</span>)</span><br><span class="line">        func(*args, **kwargs)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录,end&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@mylog  </span><span class="comment"># 本质 fun1 = mylog(fun1)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun1</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能1&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@mylog  </span><span class="comment"># 本质 fun2 = mylog(fun2)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>(<span class="params">a, b, c</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2&quot;</span>, a, b, c)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">fun1()</span><br><span class="line">fun2(<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能1</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">日志记录,start</span></span><br><span class="line"><span class="string">使用功能2 10 20 30</span></span><br><span class="line"><span class="string">日志记录,end</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="多个装饰器"><a href="#多个装饰器" class="headerlink" title="多个装饰器"></a>多个装饰器</h3><p>有时候，我们需要多个装饰器修饰一个函数。比如：需要增加日志功能、增加执行效率测试功能。</p>
<p>装饰器函数的执行顺序是分为（被装饰函数）定义阶段和（被装饰函数）执行阶段的，装饰器函数在被装饰函数定义好后立即执行。</p>
<blockquote>
<p>在函数定义阶段：执行顺序是从最靠近函数的装饰器开始，自内而外的执行</p>
<p>在函数执行阶段：执行顺序由外而内，一层层执行</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mylog</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;mylog start&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录开始&quot;</span>)</span><br><span class="line">        func()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录结束&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;mylog end&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">cost_time</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;cost time start&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;开始计时&quot;</span>)</span><br><span class="line">        start = time.time()</span><br><span class="line">        func()</span><br><span class="line">        end = time.time()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;耗费时间：<span class="subst">&#123;end - start&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;cost time start&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 等价于 mylog(cost_time(fun2))</span></span><br><span class="line"><span class="meta">@mylog</span></span><br><span class="line"><span class="meta">@cost_time</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;fun2,start&quot;</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;fun2,end&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">fun2()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">cost time start</span></span><br><span class="line"><span class="string">cost time start</span></span><br><span class="line"><span class="string">mylog start</span></span><br><span class="line"><span class="string">mylog end</span></span><br><span class="line"><span class="string">日志记录开始</span></span><br><span class="line"><span class="string">开始计时</span></span><br><span class="line"><span class="string">fun2,start</span></span><br><span class="line"><span class="string">fun2,end</span></span><br><span class="line"><span class="string">耗费时间：3.014333486557007</span></span><br><span class="line"><span class="string">日志记录结束</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="带参数的装饰器"><a href="#带参数的装饰器" class="headerlink" title="带参数的装饰器"></a>带参数的装饰器</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mylog</span>(<span class="params"><span class="built_in">type</span></span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">type</span> == <span class="string">&quot;文件&quot;</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;文件中：日志记录&quot;</span>)</span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;控制台：日志记录&quot;</span>)</span><br><span class="line">            <span class="keyword">return</span> func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> decorator</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@mylog(<span class="params"><span class="string">&quot;文件&quot;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2:&quot;</span>, a, b)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    fun2(<span class="number">100</span>, <span class="number">200</span>)</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">文件中：日志记录</span></span><br><span class="line"><span class="string">使用功能2: 100 200</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="wraps装饰器"><a href="#wraps装饰器" class="headerlink" title="wraps装饰器"></a>wraps装饰器</h3><p>一个函数不止有他的执行语句，还有着 <code>__name__</code> （函数名）， <code>__doc__</code>（说明文档）等属性，我们之前的例子会导致这些属性改变。</p>
<p><code>functool.wraps</code> 可以将原函数对象的指定属性赋值给包装函数对象，默认有module、name、doc，或者通过参数选择。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mylog</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录&quot;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;函数文档：&quot;</span>, func.__doc__)</span><br><span class="line">        <span class="keyword">return</span> func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@mylog    </span><span class="comment"># 等价于 fun2 = mylog(fun2)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;强大的功能2&quot;&quot;&quot;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2:&quot;</span>, a, b)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    fun2(<span class="number">100</span>, <span class="number">200</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;函数文档---&gt;&quot;</span>, fun2.__doc__)</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">日志记录</span></span><br><span class="line"><span class="string">函数文档： 强大的功能2</span></span><br><span class="line"><span class="string">使用功能2: 100 200</span></span><br><span class="line"><span class="string">函数文档---&gt; 强大的功能2</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="内置装饰器"><a href="#内置装饰器" class="headerlink" title="内置装饰器"></a>内置装饰器</h3><p>我们在面向对象学习时，学习过三种装饰器： <code>property</code> 、 <code>staticmethod</code> 、<code>classmethod</code> 。（详见Python入门的面向对象部分）</p>
<p><strong>property装饰器</strong></p>
<p><code>property</code> 装饰器用于类中的函数，使得我们可以像访问属性一样来获取一个函数的返回值。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Employee</span>:</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, salary</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.__salary = salary</span><br><span class="line"></span><br><span class="line"><span class="meta">    @property                      </span><span class="comment"># 只能读 print(emp1.salary) 相当于属性的调用</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">salary</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;薪资是：&quot;</span>, self.__salary)</span><br><span class="line">        <span class="keyword">return</span> self.__salary</span><br><span class="line"></span><br><span class="line"><span class="meta">    @salary.setter                 </span><span class="comment"># 修改使用这个函数 emp1.salary = 50000</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">salary</span>(<span class="params">self, salary</span>): </span><br><span class="line">        <span class="keyword">if</span> <span class="number">0</span> &lt; salary &lt; <span class="number">100000</span>:</span><br><span class="line">            self.__salary = salary</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;薪资录入错误！只能在0-100000之间&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">emp1 = Employee(<span class="string">&quot;john&quot;</span>, <span class="number">20000</span>)</span><br><span class="line">emp1.salary = <span class="number">50000</span></span><br><span class="line"><span class="built_in">print</span>(emp1.salary)</span><br><span class="line"></span><br><span class="line">emp1.salary = <span class="number">100000000</span></span><br><span class="line"><span class="built_in">print</span>(emp1.salary)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">薪资是： 50000</span></span><br><span class="line"><span class="string">50000</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">薪资录入错误！只能在0-100000之间</span></span><br><span class="line"><span class="string">薪资是： 50000</span></span><br><span class="line"><span class="string">50000</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p><strong>staticmethod装饰器</strong></p>
<p><code>staticmethod</code> 装饰器同样是用于类中的方法，这表示这个方法将会是一个静态方法，意味着该方法可以直接被调用无需实例化，但同样意味着它没有 <code>self</code> 参数，也无法访问实例化后的对象。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>:</span><br><span class="line">    school = <span class="string">&quot;HNU&quot;</span>  <span class="comment"># 类属性</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">a, b</span>):  <span class="comment"># 静态方法</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;&#123;0&#125;+&#123;1&#125;=&#123;2&#125;&quot;</span>.<span class="built_in">format</span>(a, b, a + b))</span><br><span class="line">        <span class="keyword">return</span> a+b</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Student.add(<span class="number">30</span>, <span class="number">40</span>)</span><br></pre></td></tr></table></figure>
<p><strong>classmethod装饰器</strong></p>
<p><code>classmethod</code> 这个方法是一个类方法。该方法无需实例化，没有 <code>self</code> 参数。相对于 <code>staticmethod</code> 的区别在于它会接收一个指向类本身的 <code>cls</code> 参数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>:</span><br><span class="line">    school = <span class="string">&quot;HNU&quot;</span>  <span class="comment"># 类属性</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">printSchool</span>(<span class="params">cls</span>):</span><br><span class="line">        <span class="built_in">print</span>(cls.school)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Student.printSchool()</span><br></pre></td></tr></table></figure>
<h3 id="类装饰器"><a href="#类装饰器" class="headerlink" title="类装饰器"></a>类装饰器</h3><p>上面写的装饰器都是函数来完成的。我们用类也可以实现装饰器。</p>
<p>类能实现装饰器的功能， 是由于当我们调用一个对象时，实际上调用的是它的 <code>__call__</code> 方法。</p>
<p>调用对象， <code>__call__</code> 方法的使用</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Demo</span>:</span><br><span class="line">	<span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self</span>):</span><br><span class="line">	<span class="built_in">print</span>(<span class="string">&#x27;我是Demo&#x27;</span>)</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">demo Demo()</span><br><span class="line">demo()		<span class="comment"># 直接调用对象，实质是调用了他的__ca11__()</span></span><br></pre></td></tr></table></figure>
<p>类装饰器的使用案例</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 类装饰器</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyLogDecorator</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, func</span>):</span><br><span class="line">        self.func = func</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self, *args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志记录&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> self.func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@MyLogDecorator  </span><span class="comment"># fun2 = MyLogDecorator(fun2)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun2</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;使用功能2&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    fun2()</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">日志记录</span></span><br><span class="line"><span class="string">使用功能2</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="缓存装饰器和计时装饰器综合练习"><a href="#缓存装饰器和计时装饰器综合练习" class="headerlink" title="缓存装饰器和计时装饰器综合练习"></a>缓存装饰器和计时装饰器综合练习</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CacheDecorator</span>():</span><br><span class="line">    __cache = &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, func</span>):</span><br><span class="line">        self.func = func</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self, *args, **kwargs</span>):</span><br><span class="line">        <span class="comment"># 如果缓存中有对应的方法名，则直接返回对应的返回值</span></span><br><span class="line">        <span class="keyword">if</span> self.func.__name__ <span class="keyword">in</span> CacheDecorator.__cache:</span><br><span class="line">            <span class="keyword">return</span> CacheDecorator.__cache[self.func.__name__]</span><br><span class="line">        <span class="comment"># 如果缓存中没有对应的方法名，则进行计算，并将结果缓存</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            result = self.func(*args, **kwargs)</span><br><span class="line">            CacheDecorator.__cache[self.func.__name__] = result</span><br><span class="line">            <span class="keyword">return</span> result</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">cost_time</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">infunc</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        start = time.time()</span><br><span class="line">        result = func(*args, **kwargs)</span><br><span class="line">        end = time.time()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;耗时：<span class="subst">&#123;end - start&#125;</span>&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> result</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> infunc</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@cost_time</span></span><br><span class="line"><span class="meta">@CacheDecorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func1_long_time</span>():</span><br><span class="line">    <span class="string">&quot;&quot;&quot;模拟耗时较长，每次执行返回结果都一样的情况&quot;&quot;&quot;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;start func1&quot;</span>)</span><br><span class="line">    time.sleep(<span class="number">3</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;end func1&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="number">999</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;第一次执行&quot;</span>)</span><br><span class="line">    r1 = func1_long_time()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;第二次执行&quot;</span>)</span><br><span class="line">    r2 = func1_long_time()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;打印结果：&quot;</span>)</span><br><span class="line">    <span class="built_in">print</span>(r1)</span><br><span class="line">    <span class="built_in">print</span>(r2)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">第一次执行</span></span><br><span class="line"><span class="string">start func1</span></span><br><span class="line"><span class="string">end func1</span></span><br><span class="line"><span class="string">耗时：3.009289264678955</span></span><br><span class="line"><span class="string">第二次执行</span></span><br><span class="line"><span class="string">耗时：0.0</span></span><br><span class="line"><span class="string">打印结果：</span></span><br><span class="line"><span class="string">999</span></span><br><span class="line"><span class="string">999</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h2 id="生成器、迭代器、动态性"><a href="#生成器、迭代器、动态性" class="headerlink" title="生成器、迭代器、动态性"></a>生成器、迭代器、动态性</h2><h3 id="生成器"><a href="#生成器" class="headerlink" title="生成器"></a>生成器</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191849880.png" alt="image-20240107222700567"></p>
<h4 id="生成器定义"><a href="#生成器定义" class="headerlink" title="生成器定义"></a>生成器定义</h4><p>在Python中，一边循环一边计算的机制，称为生成器：generator</p>
<h4 id="为什么要有生成器"><a href="#为什么要有生成器" class="headerlink" title="为什么要有生成器"></a>为什么要有生成器</h4><p>列表所有数据都在内存中，如果有海量数据的话将会非常耗内存。</p>
<p>如：仅仅需要访问前面几个元素，那后面绝大多数元素占用的空间都白白浪费了。</p>
<p>如果列表元素按照某种算法推算出来，那我们就可以在循环的过程中不断推算出后续的元素，这样就不必创建完整的list，从而节省大</p>
<p>量的空间。</p>
<p><strong>简单说：</strong></p>
<p>时间换空间！想要得到庞大的数据，又想让它占用空间少，那就用生成器！</p>
<p>延迟计算！需要的时候，再计算出数据！</p>
<h4 id="创建生成器的方式一（生成器表达式）"><a href="#创建生成器的方式一（生成器表达式）" class="headerlink" title="创建生成器的方式一（生成器表达式）"></a>创建生成器的方式一（生成器表达式）</h4><p>生成器表达式很简单，只要把一个列表推导式的 <code>[]</code> 改成 <code>()</code> ，就创建了一个生成器(generator)：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line">L = [x * x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)]</span><br><span class="line"><span class="built_in">print</span>(L)</span><br><span class="line">g = (x * x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>))</span><br><span class="line"><span class="built_in">print</span>(g)</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</span></span><br><span class="line"><span class="string">&lt;generator object &lt;genexpr&gt; at 0x000002AD5900C430&gt;</span></span><br><span class="line"><span class="string">0</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">4</span></span><br><span class="line"><span class="string">9</span></span><br><span class="line"><span class="string">16</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>创建 L 和 g 的区别仅在于最外层的 <code>[]</code> 和 <code>()</code> ， L 是一个list，而 g 是一个generator。</p>
<h4 id="创建生成器的方式二（生成器函数）"><a href="#创建生成器的方式二（生成器函数）" class="headerlink" title="创建生成器的方式二（生成器函数）"></a>创建生成器的方式二（生成器函数）</h4><blockquote>
<p>如果一个函数中包含 <code>yield</code> 关键字，那么这个函数就不再是一个普通函数，调用函数就是创建了一个生成器（generator）对象。</p>
<p>生成器函数：其实就是利用关键字 <code>yield</code> 一次性返回一个结果，阻塞，重新开始</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">1.函数有了yield之后，调用它，就会生成一个生成器</span></span><br><span class="line"><span class="string">2.yield的作用：程序挂起，返回相应的值。下次从下一个语句开始执行。</span></span><br><span class="line"><span class="string">3.return在生成器中代表生成器终止，直接报错：StopIteration</span></span><br><span class="line"><span class="string">4.next方法作用：唤醒并继续执行</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">demo</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;start&quot;</span>)</span><br><span class="line">    i = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> i &lt; <span class="number">3</span>:</span><br><span class="line">        <span class="keyword">yield</span> i</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;i:<span class="subst">&#123;i&#125;</span>&quot;</span>)</span><br><span class="line">        i += <span class="number">1</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;done&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    a = demo()</span><br><span class="line">    <span class="built_in">print</span>(a)</span><br><span class="line">    a.__next__()</span><br><span class="line">    a.__next__()</span><br><span class="line">    a.__next__()</span><br><span class="line">    a.__next__()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">Traceback (most recent call last):</span></span><br><span class="line"><span class="string">  File &quot;D:\2022百战Python\函数式编程和核心特性\生成器、迭代器、动态性\生成器函数的创建_yield.py&quot;, line 27, in &lt;module&gt;</span></span><br><span class="line"><span class="string">    a.__next__()</span></span><br><span class="line"><span class="string">StopIteration: done</span></span><br><span class="line"><span class="string">&lt;generator object demo at 0x000001B4F30DC430&gt;</span></span><br><span class="line"><span class="string">start</span></span><br><span class="line"><span class="string">i:0</span></span><br><span class="line"><span class="string">i:1</span></span><br><span class="line"><span class="string">i:2</span></span><br><span class="line"><span class="string">end</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="生成器函数的工作原理"><a href="#生成器函数的工作原理" class="headerlink" title="生成器函数的工作原理"></a>生成器函数的工作原理</h4><p>原理是这样的：</p>
<ol>
<li>生成器函数返回一个迭代器，for循环对这个迭代器不断调用 <code>__next__()</code> 函数，不断运行到下一个<code>yield</code> 语句，一次一次取得每一个返回值，直到没有 <code>yield</code> 语句为止，最终引发 <code>StopIteration</code> 异常。</li>
<li><code>yield</code> 相当于 <code>return</code> 返回一个值，并且记住这个返回的位置，下次迭代时，代码从 <code>yield</code> 的<strong>下一条语句(不是下一行)</strong>开始执行。</li>
<li><code>send()</code> 和 <code>next()</code> 一样，都能让生成器继续往下走一步（下次遇到 <code>yield</code> 停），但 <code>send()</code> 能传一个值，这个值作为 <code>yield</code> 表达式整体的结果</li>
</ol>
<blockquote>
<p>生成器推导式底层原理也是这样的。</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># send的作用是唤醒并继续执行，发送一个消息到生成器内部</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">foo</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;start&quot;</span>)</span><br><span class="line">    i = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> i &lt; <span class="number">3</span>:</span><br><span class="line">        temp = <span class="keyword">yield</span> i</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;temp:<span class="subst">&#123;temp&#125;</span>&quot;</span>)</span><br><span class="line">        i += <span class="number">1</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">g = foo()</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(g))  <span class="comment"># g.__next__()</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">10</span>)</span><br><span class="line"><span class="built_in">print</span>(g.send(<span class="number">100</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(g))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">start</span></span><br><span class="line"><span class="string">0</span></span><br><span class="line"><span class="string">**********</span></span><br><span class="line"><span class="string">temp:100</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">temp:None</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><p>什么是生成器？</p>
<blockquote>
<p>生成器仅仅保存了一套生成数值的算法，并且没有让这个算法现在就开始执行，而是我什么时候调它，它什么时候开始</p>
<p>计算一个新的值，并给你返回。</p>
</blockquote>
<p>生成器特点：</p>
<blockquote>
<ol>
<li>生成器函数生成一系列结果。通过 <code>yield</code> 关键字返回一个值后，还能从其退出的地方继续运行，因此可以随时间产生一系列的值。</li>
<li>生成器和迭代是密切相关的，<strong>迭代器都有一个</strong> <code>__next__()</code> <strong>成员方法，</strong>这个方法要么返回迭代的下一项，要么引起异常结束迭代。</li>
<li>生成器是一个特殊的程序，可以被用作控制循环的迭代行为，Python中生成器是迭代器的一种，使用<code>yield</code>返回值函数，每次调用<code>yield</code>会暂停，而可以使用 <code>next()</code> 函数和<code>send()</code> 函数恢复生成器。</li>
<li>生成器看起来像是一个函数，但是表现得却像是迭代器</li>
</ol>
</blockquote>
<h3 id="迭代器"><a href="#迭代器" class="headerlink" title="迭代器"></a>迭代器</h3><h4 id="概念-1"><a href="#概念-1" class="headerlink" title="概念"></a>概念</h4><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191850299.png" alt="image-20240109000525212"></p>
<ol>
<li>迭代是Python最强大的功能之一，是访问集合元素的一种方式。</li>
<li>迭代器是一个可以<strong>记住遍历的位置</strong>的对象。</li>
<li>迭代器对象从集合的第一个元素开始访问，直到所有的元素被访问完结束。</li>
<li>迭代器只能往前不会后退。</li>
<li>迭代器有两个基本的方法： <code>iter()</code> 和 <code>next()</code></li>
</ol>
<h4 id="可迭代对象和迭代器区别"><a href="#可迭代对象和迭代器区别" class="headerlink" title="可迭代对象和迭代器区别"></a>可迭代对象和迭代器区别</h4><ol>
<li>一个实现了 <code>iter</code> 方法的对象，称为”可迭代对象Ieratable”</li>
<li>一个实现 了<code>next</code> 方法并且是可迭代的对象，称为”迭代器Iterator”</li>
</ol>
<blockquote>
<p>即：实现了 <code>iter</code> 方法和 <code>next</code> 方法的对象就是迭代器。</p>
<p>:warning:生成器都是 <code>Iterator</code> 对象，但 <code>list</code> 、 <code>dict</code> 、 <code>str</code> 虽然是 <code>Iterable（可迭代对象）</code> ，却不是 <code>Iterator（迭代器）</code> 。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># python3.6之前不加.abc，之后的加</span></span><br><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> Iterator</span><br><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> Iterable</span><br><span class="line"></span><br><span class="line">a = <span class="built_in">isinstance</span>([], Iterable)</span><br><span class="line">a = <span class="built_in">isinstance</span>([], Iterator)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">False</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p><code>list</code> 、 <code>dict</code> 、 <code>str</code> 等 <code>Iterable</code> 变成 <code>Iterator</code> , 可以使用 <code>iter()</code> 函数：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(<span class="built_in">iter</span>([]), Iterator)</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">isinstance</span>(<span class="built_in">iter</span>(<span class="string">&#x27;abc&#x27;</span>), Iterator)</span><br><span class="line"><span class="literal">True</span></span><br></pre></td></tr></table></figure>
</blockquote>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191850844.png" alt="image-20240109000916190"></p>
<p>为什么 <code>list</code> 、 <code>dict</code> 、 <code>str</code> 等数据类型不是 <code>Iterator</code> ？</p>
<p>Python的 <code>Iterator</code> 对象表示的是一个<strong>数据流</strong>。可以把这个数据流看做是一个有序序列，但我们却不能提前知道序列的长度，只能不断通过 <code>next()</code> 函数实现按需计算下一个数据，所以 <code>Iterator</code> 的计算是惰性的，只有在需要返回下一个数据时它才会计算。</p>
<p>所以，生成器一定是迭代器。</p>
<p><code>Iterator</code> 甚至可以表示一个无限大的数据流，例如全体自然数。而使用<code>list</code>是永远不可能存储全体自然数的。</p>
<h4 id="for循环的本质"><a href="#for循环的本质" class="headerlink" title="for循环的本质"></a>for循环的本质</h4><p>Python3的 for 循环本质上就是通过不断调用 <code>next()</code> 函数实现的。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]:</span><br><span class="line">	<span class="keyword">pass</span></span><br></pre></td></tr></table></figure>
<p>本质是：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 首先获得Iterator对象:</span></span><br><span class="line">it = <span class="built_in">iter</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>])</span><br><span class="line"><span class="comment"># 循环:</span></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">	<span class="comment"># 获得下一个值:</span></span><br><span class="line">	x = <span class="built_in">next</span>(it)</span><br><span class="line"><span class="keyword">except</span> StopIteration:</span><br><span class="line">    <span class="comment"># 遇到StopIteration就退出循环</span></span><br><span class="line">	<span class="keyword">break</span></span><br></pre></td></tr></table></figure>
<h4 id="创建一个迭代器"><a href="#创建一个迭代器" class="headerlink" title="创建一个迭代器"></a>创建一个迭代器</h4><p>一个类作为一个迭代器使用需要在类中实现两个方法 <code>__iter__()</code> 与<code>__next__()</code></p>
<ol>
<li><code>__iter__()</code> 方法返回一个特殊的迭代器对象， 这个迭代器对象实现了 <code>__next__()</code> 方法并通过<code>StopIteration</code> 异常标识迭代的完成。</li>
<li><code>__next__()</code> 方法会返回下一个迭代器对象。 </li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 创建一个依次返回10,20,30,...这样数字的迭代器</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyNumbers</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):</span><br><span class="line">        self.num = <span class="number">10</span></span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">if</span> self.num &lt; <span class="number">40</span>:</span><br><span class="line">            x = self.num</span><br><span class="line">            self.num += <span class="number">10</span></span><br><span class="line">            <span class="keyword">return</span> x</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">raise</span> StopIteration</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">myclass = MyNumbers()</span><br><span class="line">myiter = <span class="built_in">iter</span>(myclass)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(myiter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(myiter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(myiter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(myiter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(myiter))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">10</span></span><br><span class="line"><span class="string">20</span></span><br><span class="line"><span class="string">30</span></span><br><span class="line"><span class="string">Traceback (most recent call last):</span></span><br><span class="line"><span class="string">  File &quot;D:\2022百战Python\函数式编程和核心特性\生成器、迭代器、动态性\创建一个迭代器.py&quot;, line 22, in &lt;module&gt;</span></span><br><span class="line"><span class="string">    print(next(myiter))</span></span><br><span class="line"><span class="string">  File &quot;D:\2022百战Python\函数式编程和核心特性\生成器、迭代器、动态性\创建一个迭代器.py&quot;, line 14, in __next__</span></span><br><span class="line"><span class="string">    raise StopIteration</span></span><br><span class="line"><span class="string">StopIteration</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="动态添加属性和方法"><a href="#动态添加属性和方法" class="headerlink" title="动态添加属性和方法"></a>动态添加属性和方法</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191851313.png" alt="image-20240109002706032"></p>
<p>动态编程语言是高级程序设计语言的一个类别，在计算机科学领域已被广泛应用。</p>
<p>它是指在运行时可以改变其结构的语言 ：例如新的函数、 对象、甚至代码可以被引进，已有的函数可以被删除或是其他结构上的变化。</p>
<h4 id="给对象动态的添加属性和方法"><a href="#给对象动态的添加属性和方法" class="headerlink" title="给对象动态的添加属性和方法"></a>给对象动态的添加属性和方法</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> types</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">p1 = Person(<span class="string">&quot;jhon&quot;</span>, <span class="number">20</span>)</span><br><span class="line">p2 = Person(<span class="string">&quot;parker&quot;</span>, <span class="number">20</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态给对象添加属性</span></span><br><span class="line">p1.score = <span class="number">100</span></span><br><span class="line"><span class="built_in">print</span>(p1.score)</span><br><span class="line"><span class="comment"># 只给p1添加了属性，p2没有</span></span><br><span class="line"><span class="comment"># print(p2.score)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态给对象添加方法</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">run</span>(<span class="params">self</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>, running&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># types.MethodType(run,p1)则是告诉解释器，self指的就是p1</span></span><br><span class="line">p1.run = types.MethodType(run, p1)</span><br><span class="line">p1.run()</span><br></pre></td></tr></table></figure>
<h4 id="type-MethonType的使用"><a href="#type-MethonType的使用" class="headerlink" title="type.MethonType的使用"></a>type.MethonType的使用</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># types.MethodType(run,p1)则是告诉解释器，self指的就是p1</span></span><br></pre></td></tr></table></figure>
<h4 id="给类动态的添加属性、静态方法以及类方法"><a href="#给类动态的添加属性、静态方法以及类方法" class="headerlink" title="给类动态的添加属性、静态方法以及类方法"></a>给类动态的添加属性、静态方法以及类方法</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@staticmethod</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">staticfunc</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;---static method---&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态给类添加静态方法</span></span><br><span class="line">Person.staticfunc = staticfunc</span><br><span class="line">Person.staticfunc()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@classmethod</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">clsfunc</span>(<span class="params">cls</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;---cls method---&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态给类添加类方法</span></span><br><span class="line">Person.clsfunc = clsfunc</span><br><span class="line">Person.clsfunc()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态给类添加属性</span></span><br><span class="line">Person.sorce = <span class="number">100</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="slots-的作用"><a href="#slots-的作用" class="headerlink" title="__slots__ 的作用"></a><code>__slots__</code> 的作用</h4><ol>
<li><code>__slots__</code> 对==动态添加成员变量、成员方法有限制==。<strong>对动态添加类属性、类方法没有限制</strong>。 </li>
<li><code>__slots__</code> 只对本类有限制，不限制子类。</li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>():</span><br><span class="line">    __slots__ = &#123;<span class="string">&quot;name&quot;</span>, <span class="string">&quot;age&quot;</span>&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">eat</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;eat!!!&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    p1 = Person(<span class="string">&quot;jhon&quot;</span>, <span class="number">21</span>)</span><br><span class="line">    <span class="comment"># p1.gender = &quot;man&quot;</span></span><br><span class="line">    <span class="comment"># AttributeError: &#x27;Person&#x27; object has no attribute &#x27;gender&#x27;</span></span><br></pre></td></tr></table></figure>
<h2 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h2><h3 id="正则表达式概念"><a href="#正则表达式概念" class="headerlink" title="正则表达式概念"></a>正则表达式概念</h3><p>正则表达式是对字符串操作的一种逻辑公式，就是用事先定义好的一些特定字符、及这些特定字符的组合，组成一个“规则字符串”，这个“规则字符串”用来表达对字符串的一种过滤逻辑（可以用来做检索，截取或者替换操作）。</p>
<p>作用</p>
<ol>
<li>给定的字符串是否符合正则表达式的过滤逻辑（称作“匹配”）。</li>
<li>可以通过正则表达式，从字符串中获取我们想要的特定部分。</li>
<li>还可以对目标字符串进行替换操作。</li>
</ol>
<p>基本函数</p>
<p>Python语言通过标准库中的<code>re</code>模块支持正则表达式。<code>re</code>模块提供了一些根据正则表达式进行查找、替换、分隔字符串的函数，</p>
<p>这些函数使用一个正则表达式作为第一个参数。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th><strong>函数</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>match(pattern,string,flags=0)</code></td>
<td>根据pattern从string的头部开始匹配字符串，只返回第1次匹配成功的对象；否则，返回None</td>
</tr>
<tr>
<td><code>findall(pattern,string,flags=0)</code></td>
<td>根据pattern在string中匹配字符串。如果匹配成功，返回包含匹配结果的列表；否则，返回空列表。当pattern中有分组时，返回包含多个元组的列表，每个元组对应1个分组。flags表示规则选项，规则选项用于辅助匹配。</td>
</tr>
<tr>
<td><code>sub(pattern,repl,string,count=0)</code></td>
<td>根据指定的正则表达式，替换源字符串中的子串。pattern是一个正则表达式，repl是用于替换的字符串，string是源字符串。如果count等于0，则返回string中匹配的所有结果；如果count大于0，则返回前count个匹配结果</td>
</tr>
<tr>
<td><code>subn(pattern,repl,string,count=0)</code></td>
<td>作用和sub()相同，返回一个二元的元组。第1个元素是替换结果，第2个元素是替换的次数</td>
</tr>
<tr>
<td><code>search(pattern,string,flags=0)</code></td>
<td>根据pattern在string中匹配字符串，只返回第1次匹配成功的对象。如果匹配失败，返回None</td>
</tr>
<tr>
<td><code>compile(pattern,flags=0)</code></td>
<td>编译正则表达式pattern，返回1个pattern的对象</td>
</tr>
<tr>
<td><code>split(pattern,string,maxsplit=0)</code></td>
<td>根据pattern分隔string，maxsplit表示最大的分隔数</td>
</tr>
<tr>
<td><code>escape(pattern)</code></td>
<td>匹配字符串中的特殊字符，如*、+、?等</td>
</tr>
</tbody>
</table>
</div>
<h3 id="match函数的使用"><a href="#match函数的使用" class="headerlink" title="match函数的使用"></a>match函数的使用</h3><p><code>re.match</code> 尝试从字符串的<strong>起始位置匹配一个模式</strong>，如果不是起始位置匹配成功的话，match()就返回None。语法格式如下：</p>
<p><code>re.match(pattern, string, flags=0)</code></p>
<div class="table-container">
<table>
<thead>
<tr>
<th><strong>参数</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>匹配的正则表达式</td>
</tr>
<tr>
<td>string</td>
<td>要匹配的字符串</td>
</tr>
<tr>
<td>flags</td>
<td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。如下表列出正则表达式修饰符 - 可选标志</td>
</tr>
</tbody>
</table>
</div>
<p><strong>正则表达式修饰符</strong></p>
<div class="table-container">
<table>
<thead>
<tr>
<th><strong>修饰符</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>re.I</td>
<td>使匹配对大小写不敏感</td>
</tr>
<tr>
<td>re.L</td>
<td>做本地化识别（locale-aware）匹配</td>
</tr>
<tr>
<td>re.M</td>
<td>多行匹配，影响 ^ 和 $</td>
</tr>
<tr>
<td>re.S</td>
<td>使 . 匹配包括换行在内的所有字符</td>
</tr>
<tr>
<td>re.U</td>
<td>根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B</td>
</tr>
<tr>
<td>re.X</td>
<td>该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。</td>
</tr>
</tbody>
</table>
</div>
<p>意义：</p>
<ol>
<li><code>re.match</code>是用来进行正则匹配检查的方法，如果字符串开头的0个或多个字符匹配正则表达式模式，则返回相应的match对象。如果字符串不匹配模式，返回None（注意不是空字符串””）</li>
<li>匹配对象Match Object具有<code>group()</code>方法， 用来返回字符串的匹配部分。具有<code>span()</code>方法，返回匹配字符串的位置（元组存储开始，结束位置）。具有<code>start()</code>，<code>end()</code>方法，存储匹配数据的开始和结束位置。（也可以通过对象的dir(对象查看对象的方法)）</li>
</ol>
<blockquote>
<p>:warning:<strong>注意：</strong></p>
<p>如果想在目标字符串的==任意位置查找==，需要使用search</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义正则表达式</span></span><br><span class="line">pattern = <span class="string">&quot;hello&quot;</span></span><br><span class="line"><span class="comment"># 目标字符串</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;hello world&quot;</span></span><br><span class="line"><span class="comment"># match函数的使用</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">dir</span>(result))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;匹配内容：&quot;</span>, result.group())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;匹配字符串的位置: &quot;</span>, result.span())</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 5), match=&#x27;hello&#x27;&gt;</span></span><br><span class="line"><span class="string">[&#x27;__class__&#x27;, &#x27;__class_getitem__&#x27;, &#x27;__copy__&#x27;, &#x27;__deepcopy__&#x27;, &#x27;__delattr__&#x27;, &#x27;__dir__&#x27;, &#x27;__doc__&#x27;, &#x27;__eq__&#x27;, &#x27;__format__&#x27;, &#x27;__ge__&#x27;, &#x27;__getattribute__&#x27;, &#x27;__getitem__&#x27;, &#x27;__gt__&#x27;, &#x27;__hash__&#x27;, &#x27;__init__&#x27;, &#x27;__init_subclass__&#x27;, &#x27;__le__&#x27;, &#x27;__lt__&#x27;, &#x27;__ne__&#x27;, &#x27;__new__&#x27;, &#x27;__reduce__&#x27;, &#x27;__reduce_ex__&#x27;, &#x27;__repr__&#x27;, &#x27;__setattr__&#x27;, &#x27;__sizeof__&#x27;, &#x27;__str__&#x27;, &#x27;__subclasshook__&#x27;, &#x27;end&#x27;, &#x27;endpos&#x27;, &#x27;expand&#x27;, &#x27;group&#x27;, &#x27;groupdict&#x27;, &#x27;groups&#x27;, &#x27;lastgroup&#x27;, &#x27;lastindex&#x27;, &#x27;pos&#x27;, &#x27;re&#x27;, &#x27;regs&#x27;, &#x27;span&#x27;, &#x27;start&#x27;, &#x27;string&#x27;]</span></span><br><span class="line"><span class="string">匹配内容： hello</span></span><br><span class="line"><span class="string">匹配字符串的位置:  (0, 5)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义正则表达式</span></span><br><span class="line">pattern = <span class="string">&quot;hello&quot;</span></span><br><span class="line"><span class="comment"># 目标字符串</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;Hello world&quot;</span></span><br><span class="line"><span class="comment"># match函数的使用</span></span><br><span class="line"><span class="comment"># 忽略大小写</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>, re.I)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br></pre></td></tr></table></figure>
<h3 id="常用匹配符"><a href="#常用匹配符" class="headerlink" title="常用匹配符"></a>常用匹配符</h3><p>一个正则表达式是由字母、数字和特殊字符（括号、星号、问号等）组成。正则表达式中有许多特殊的字符，这些特殊字符是构成正则表达式的要素。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>符号</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>.</td>
<td>匹配任何一个字符（除了\n）</td>
</tr>
<tr>
<td>[]</td>
<td>匹配列表中的字符</td>
</tr>
<tr>
<td>\w</td>
<td>匹配字母、数字、下划线，即a-z,A-Z,0-9,_</td>
</tr>
<tr>
<td>\W</td>
<td>匹配不是字母、数字、下划线</td>
</tr>
<tr>
<td>\s</td>
<td>匹配空白字符，即空格（\n,\t）</td>
</tr>
<tr>
<td>\S</td>
<td>匹配不是空白的字符</td>
</tr>
<tr>
<td>\d</td>
<td>匹配数字，即0-9</td>
</tr>
<tr>
<td>\D</td>
<td>匹配非数字的字符</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 常用匹配符.的使用：匹配任意一个字符（除了\n）</span></span><br><span class="line">pattern = <span class="string">&quot;.&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;9&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;a&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;B&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\d的使用：匹配数字</span></span><br><span class="line">pattern = <span class="string">&quot;\d&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;0&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;a&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;B&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\D的使用：匹配非数字</span></span><br><span class="line">pattern = <span class="string">&quot;\D&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;a&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;B&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\s的使用：匹配空白字符,即空格（\n,\t）</span></span><br><span class="line">pattern = <span class="string">&quot;\s&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot; &quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;\n&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;\t&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\S的使用：匹配不是空白的字符</span></span><br><span class="line">pattern = <span class="string">&quot;\S&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;a&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;B&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\w的使用：匹配字母、数字、下划线</span></span><br><span class="line">pattern = <span class="string">&quot;\w&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;a&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;8&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 常用匹配符\W的使用：匹配不是字母、数字、下划线</span></span><br><span class="line">pattern = <span class="string">&quot;\W&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;#&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;@&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># []匹配列表中的字符</span></span><br><span class="line">pattern = <span class="string">&quot;[12345]&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;1&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;2&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;3&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 匹配手机号码</span></span><br><span class="line">s = <span class="string">&quot;13456788789&quot;</span></span><br><span class="line">pattern = <span class="string">&quot;1[35789]\d\d\d\d\d\d\d\d\d&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;匹配手机号码：&quot;</span>, re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;9&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;0&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;a&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;\n&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;a&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;a&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;#&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;1&#x27;&gt;</span></span><br><span class="line"><span class="string">匹配手机号码： &lt;re.Match object; span=(0, 11), match=&#x27;13456788789&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>其中，匹配符“[]”可以指定一个范围，例如：“[ok]”将匹配包含“o”或“k”的字符。同时“[]”可以与\w、\s、\d等标记等价。例如，<code>[0-9a-zAZ]</code>等价于\w，<code>[ ^0-9 ]</code> 等价于\D。</p>
<h3 id="限定符"><a href="#限定符" class="headerlink" title="限定符"></a>限定符</h3><p>从上面示例中可以看到如果要匹配手机号码，需要形如<code>\d\d\d\d\d\d\d\d\d\d\d</code>这样的正则表达式。其中表现了11次<code>\d</code>，表达方式烦琐。正则表达式作为一门小型的语言，还提供了对表达式的一部分进行重复处理的功能。例如，<code>*</code>可以对正则表达式的某个部分重复匹配多次。这种匹配符号称为限定符。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>符号</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>*</td>
<td>匹配零次或多次</td>
</tr>
<tr>
<td>+</td>
<td>匹配一次或多次</td>
</tr>
<tr>
<td>?</td>
<td>匹配一次或零次</td>
</tr>
<tr>
<td>{m}</td>
<td>重复m次</td>
</tr>
<tr>
<td>{m,n}</td>
<td>重复m到n次，其中n可以省略，表示m到任意次</td>
</tr>
<tr>
<td>{m,}</td>
<td>重复至少m次</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 限定符 *、+、? 的使用</span></span><br><span class="line"><span class="comment"># * 匹配0次或多次</span></span><br><span class="line">partten = <span class="string">&quot;\d*&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123abc&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;abc&quot;   # re.Match object; span=(0, 0), match=&#x27;&#x27;&gt;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># + 匹配1次或多次</span></span><br><span class="line">partten = <span class="string">&quot;\d+&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123abc&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;abc&quot;   # None</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># ? 匹配1次或0次</span></span><br><span class="line">partten = <span class="string">&quot;\d?&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123abc&quot;</span></span><br><span class="line"><span class="comment"># str = &quot;abc&quot;   # re.Match object; span=(0, 0), match=&#x27;&#x27;&gt;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># &#123;m&#125; 重复m次</span></span><br><span class="line">partten = <span class="string">&quot;\d&#123;3&#125;&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;1234abc&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># &#123;m,n&#125; 重复m到n次</span></span><br><span class="line">partten = <span class="string">&quot;\d&#123;3,5&#125;&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;1234abc&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># &#123;m,&#125; 重复至少m次</span></span><br><span class="line">partten = <span class="string">&quot;\d&#123;3,&#125;&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123456abc&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 3), match=&#x27;123&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 3), match=&#x27;123&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 1), match=&#x27;1&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 3), match=&#x27;123&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 4), match=&#x27;1234&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 6), match=&#x27;123456&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="限定符使用实例"><a href="#限定符使用实例" class="headerlink" title="限定符使用实例"></a>限定符使用实例</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配出一个字符串首字母为大写字符，后边都是小写字符，这些小写字母可有可无</span></span><br><span class="line">partten = <span class="string">&quot;[A-Z][a-z]*&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;Abc&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 匹配出有效的变量名</span></span><br><span class="line"><span class="comment"># partten = &quot;[A-Za-z_][A-Za-z_0-9]*&quot;</span></span><br><span class="line">partten = <span class="string">&quot;[A-Za-z_]\w*&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;Abc_&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 匹配出1-99之间的数字</span></span><br><span class="line">partten = <span class="string">&quot;[1-9]\d?&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"><span class="comment"># 匹配出一个随机密码8-20位以内 (大写字母 小写字母 下划线 数字)</span></span><br><span class="line">partten = <span class="string">&quot;\w&#123;8,20&#125;&quot;</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;123abc_12D&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, <span class="built_in">str</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 3), match=&#x27;Abc&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 4), match=&#x27;Abc_&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 2), match=&#x27;12&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 10), match=&#x27;123abc_12D&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="原生字符串"><a href="#原生字符串" class="headerlink" title="原生字符串"></a>原生字符串</h3><p>和大多数编程语言相同，正则表达式里使用<code>\</code>作为转义字符，这就可以能造成反斜杠困扰。</p>
<p>假如你需要匹配文本中的字符<code>\</code>，那么使用编程语言表示的正则表达式里将需要4个反斜杠<code>\</code>：前面两个和后两个分别用于在编程语言里转义成反斜杠，转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。</p>
<p>Python里的原生字符串很好地解决了这个问题，使用Python的r前缀。例如匹配一个数字的<code>&quot;\d&quot;</code>可以写成<code>r&quot;\d&quot;</code>。有了原生字符串，再也不用担心是不是漏写了反斜杠，写出来的表达式也更直观。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 反斜杠作为转义</span></span><br><span class="line">s = <span class="string">&quot;\n123&quot;</span></span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line">s = <span class="string">&quot;\\n123&quot;</span></span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line"><span class="comment"># 使用原生字符串 r</span></span><br><span class="line">s = <span class="string">r&quot;\n123&quot;</span></span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line"><span class="comment"># 在正则表达式中反斜杠作为转义</span></span><br><span class="line">s = <span class="string">&quot;\n123&quot;</span></span><br><span class="line">partten = <span class="string">&quot;\\n\d&#123;3&#125;&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, s))</span><br><span class="line"><span class="comment"># 目标字符串多个反斜杠</span></span><br><span class="line">s = <span class="string">&quot;\\n123&quot;</span></span><br><span class="line">partten = <span class="string">&quot;\\\\n\d&#123;3&#125;&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, s))</span><br><span class="line"><span class="comment"># 使用原生字符串 r</span></span><br><span class="line">s = <span class="string">&quot;\\\\n123&quot;</span></span><br><span class="line">partten = <span class="string">r&quot;\\\\n\d&#123;3&#125;&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(partten, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">123</span></span><br><span class="line"><span class="string">\n123</span></span><br><span class="line"><span class="string">\n123</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 4), match=&#x27;\n123&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 5), match=&#x27;\\n123&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 6), match=&#x27;\\\\n123&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="边界字符串"><a href="#边界字符串" class="headerlink" title="边界字符串"></a>边界字符串</h3><div class="table-container">
<table>
<thead>
<tr>
<th>字符</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td>^</td>
<td>匹配字符串开头</td>
</tr>
<tr>
<td>$</td>
<td>匹配字符串结尾</td>
</tr>
<tr>
<td>\b</td>
<td>匹配一个单词的边界</td>
</tr>
<tr>
<td>\B</td>
<td>匹配非单词的边界</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>:warning:<strong>注意：</strong></p>
<p><code>^</code>与<code>[^m]</code> 中的<code>^</code>的含义并不相同，后者<code>^</code>表示“除了….”的意思</p>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配字符串结尾 $</span></span><br><span class="line"><span class="comment"># 匹配一个5-10为的qq邮箱</span></span><br><span class="line">pattern = <span class="string">&quot;[1-9]\d&#123;4,9&#125;@qq.com$&quot;</span></span><br><span class="line">qq = <span class="string">&quot;12345@qq.com&quot;</span></span><br><span class="line">qq = <span class="string">&quot;12345@qq.com.cn&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, qq))</span><br><span class="line"><span class="comment"># 匹配字符串开头 ^</span></span><br><span class="line">pattern = <span class="string">&quot;^hello.*&quot;</span></span><br><span class="line">s = <span class="string">&quot;hello world&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"><span class="comment"># 匹配单词边界 \b</span></span><br><span class="line"><span class="comment"># 左边界</span></span><br><span class="line">pattern = <span class="string">r&quot;.*\bqwe&quot;</span></span><br><span class="line">s = <span class="string">&quot;abc qweAB&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"><span class="comment"># 右边界</span></span><br><span class="line">pattern = <span class="string">r&quot;.*ing\b&quot;</span></span><br><span class="line">s = <span class="string">&quot;123 runing&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"><span class="comment"># 匹配非单词边界 \B</span></span><br><span class="line"><span class="comment"># 左边界</span></span><br><span class="line">pattern = <span class="string">r&quot;.*\Bqwe&quot;</span></span><br><span class="line">s = <span class="string">&quot;abc aqweBC&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"><span class="comment"># 右边界</span></span><br><span class="line">pattern = <span class="string">r&quot;.*ing\B&quot;</span></span><br><span class="line">s = <span class="string">&quot;123 runingA&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 11), match=&#x27;hello world&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 7), match=&#x27;abc qwe&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 10), match=&#x27;123 runing&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 8), match=&#x27;abc aqwe&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 10), match=&#x27;123 runing&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="search函数"><a href="#search函数" class="headerlink" title="search函数"></a>search函数</h3><p>search在一个字符串中搜索满足文本模式的字符串。语法格式如下：</p>
<p><code>re.search(pattern, string, flags=0)</code></p>
<p>函数参数与match类似</p>
<div class="table-container">
<table>
<thead>
<tr>
<th><strong>参数</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>匹配的正则表达式</td>
</tr>
<tr>
<td>string</td>
<td>要匹配的字符串</td>
</tr>
<tr>
<td>flags</td>
<td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。如下表列出正则表达式修饰符 - 可选标志</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义正则表达式</span></span><br><span class="line">pattern = <span class="string">&quot;hello&quot;</span></span><br><span class="line"><span class="comment"># 目标字符串</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;hello world&quot;</span></span><br><span class="line"><span class="comment"># search函数的使用</span></span><br><span class="line">result = re.search(pattern, <span class="built_in">str</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;匹配结果：&quot;</span>, result.group())</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 5), match=&#x27;hello&#x27;&gt;</span></span><br><span class="line"><span class="string">匹配结果： hello</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="match和search的区别"><a href="#match和search的区别" class="headerlink" title="match和search的区别"></a>match和search的区别</h4><p><code>re.match</code>只匹配字符串的开始，如果字符串开始不符合正则表达式，则匹配失败，函数返回None；而<code>re.search</code>匹配整个字符串，直到找到一个匹配。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义正则表达式</span></span><br><span class="line">pattern = <span class="string">&quot;hello&quot;</span></span><br><span class="line"><span class="comment"># 目标字符串</span></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&quot;Hello world, hello Python&quot;</span></span><br><span class="line"><span class="comment"># search函数的使用</span></span><br><span class="line">result = re.search(pattern, <span class="built_in">str</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;search:&quot;</span>, result)</span><br><span class="line">r = re.<span class="keyword">match</span>(pattern, <span class="built_in">str</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;match:&quot;</span>, r)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">search: &lt;re.Match object; span=(13, 18), match=&#x27;hello&#x27;&gt;</span></span><br><span class="line"><span class="string">match: None</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="择一匹配（-）的使用"><a href="#择一匹配（-）的使用" class="headerlink" title="择一匹配（|）的使用"></a>择一匹配（|）的使用</h3><p>search方法搜索一个字符串，要想搜索多个字符串，如搜索aa、bb和cc，最简单的方法是在文本模式字符串中使用择一匹配符号<code>|</code>。择一匹配符号和<strong>逻辑或</strong>类似，只要满足任何一个，就算匹配成功。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 择一匹配符号（|）的使用</span></span><br><span class="line">pattern = <span class="string">&quot;aa|bb|cc&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="string">&quot;aa&quot;</span>))</span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="string">&quot;bb&quot;</span>))</span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, <span class="string">&quot;cc&quot;</span>))</span><br><span class="line"><span class="built_in">print</span>(re.search(pattern, <span class="string">&quot;where is bb&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配0-100之间所有的数字</span></span><br><span class="line">s = <span class="string">&quot;0&quot;</span></span><br><span class="line">s = <span class="string">&quot;9&quot;</span></span><br><span class="line">s = <span class="string">&quot;91&quot;</span></span><br><span class="line">s = <span class="string">&quot;100&quot;</span></span><br><span class="line">s = <span class="string">&quot;101&quot;</span></span><br><span class="line">s = <span class="string">&quot;1000&quot;</span></span><br><span class="line">pattern = <span class="string">&quot;[1-9]?/d$|100$&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 2), match=&#x27;aa&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 2), match=&#x27;bb&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 2), match=&#x27;cc&#x27;&gt;</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(9, 11), match=&#x27;bb&#x27;&gt;</span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>如果待匹配的字符串中，某些字符可以有多个选择，就需要使用字符集<code>[]</code>，也就是一对中括号括起来的字符串。例如，<code>[xyz]</code>表示x、y、z三个字符可以取其中任何一个，相当于<code>x|y|z</code>，所以对单个字符使用或关系时，字符集和择一匹配符的效果是一样的。示例如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line">m = re.<span class="keyword">match</span>(<span class="string">&#x27;[xyz]&#x27;</span>, <span class="string">&#x27;x&#x27;</span>)  <span class="comment"># 匹配成功</span></span><br><span class="line"><span class="built_in">print</span>(m.group())</span><br><span class="line">m = re.<span class="keyword">match</span>(<span class="string">&#x27;x|y|z&#x27;</span>, <span class="string">&#x27;x&#x27;</span>)  <span class="comment"># 匹配成功</span></span><br><span class="line"><span class="built_in">print</span>(m.group())</span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 字符集（[]）和择一匹配符(|)的用法，及它们的差异</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配以第1个字母是a或者b，第2个字母是c或者d，如ac、bc、ad、bd</span></span><br><span class="line">m = re.<span class="keyword">match</span>(<span class="string">&#x27;[ab][cd]&#x27;</span>, <span class="string">&#x27;aceg&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(m)</span><br><span class="line"><span class="comment"># 匹配以ab开头，第3个字母是c或者d，如abc、abd</span></span><br><span class="line">m = re.<span class="keyword">match</span>(<span class="string">&#x27;ab[cd]&#x27;</span>, <span class="string">&#x27;abcd&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(m)</span><br><span class="line"><span class="comment"># 匹配ab或者cd</span></span><br><span class="line">m = re.<span class="keyword">match</span>(<span class="string">&#x27;ab|cd&#x27;</span>, <span class="string">&#x27;cd&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(m)</span><br></pre></td></tr></table></figure>
<h3 id="分组"><a href="#分组" class="headerlink" title="分组"></a>分组</h3><p>如果一个模式字符串中有用一对圆括号括起来的部分，那么这部分就会作为一组，可以通过group方法的参数获取指定的组匹配的字</p>
<p>符串。当然，如果模式字符串中没有任何用圆括号括起来的部分，那么就不会对待匹配的字符串进行分组。</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>字符</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td>(ab)</td>
<td>将括号中的字符作为一个分组</td>
</tr>
<tr>
<td>\num</td>
<td>引用分组num匹配到的字符串</td>
</tr>
<tr>
<td>(?p<name>)</td>
<td>分别起组名</td>
</tr>
<tr>
<td>(?p=name)</td>
<td>引用别名为name分组匹配到的字符串</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配座机号码  区号&#123;3，4&#125;-电话号码&#123;5，8&#125;</span></span><br><span class="line">pattern = <span class="string">&quot;/d&#123;3,4&#125;-[1-9]/d&#123;4,7&#125;$&quot;</span></span><br><span class="line">s = <span class="string">&quot;010-1234567&quot;</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, s)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用分组</span></span><br><span class="line">pattern = <span class="string">r&quot;(\d&#123;3,4&#125;)-([1-9]\d&#123;4,7&#125;$)&quot;</span></span><br><span class="line">s = <span class="string">&quot;010-1234567&quot;</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, s)</span><br><span class="line"><span class="comment"># print(result)</span></span><br><span class="line"><span class="built_in">print</span>(result.group())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;获取第一个分组结果：&quot;</span>, result.group(<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;获取第二个分组结果：&quot;</span>, result.group(<span class="number">2</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;使用groups(): &quot;</span>, result.groups())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;获取第一个分组结果：&quot;</span>, result.groups()[<span class="number">0</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;获取第二个分组结果：&quot;</span>, result.groups()[<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># \num的使用</span></span><br><span class="line">s = <span class="string">&quot;&lt;html&gt;&lt;head&gt;分组的使用&lt;/head&gt;&lt;/html&gt;&quot;</span></span><br><span class="line">s = <span class="string">&quot;&lt;html&gt;&lt;head&gt;分组的使用&lt;/body&gt;&lt;/h1&gt;&quot;</span></span><br><span class="line">pattern = <span class="string">r&quot;&lt;(.+)&gt;&lt;(.+)&gt;.+&lt;/\2&gt;&lt;/\1&gt;&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"><span class="comment"># (?P&lt;别名&gt;)</span></span><br><span class="line"><span class="comment"># 引用 (?P=别名)</span></span><br><span class="line">s = <span class="string">&quot;&lt;html&gt;&lt;head&gt;分组的使用&lt;/head&gt;&lt;/html&gt;&quot;</span></span><br><span class="line">pattern = <span class="string">r&quot;&lt;(?P&lt;k1&gt;.+)&gt;&lt;(?P&lt;k2&gt;.+)&gt;.+&lt;/(?P=k2)&gt;&lt;/(?P=k1)&gt;&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">010-1234567</span></span><br><span class="line"><span class="string">获取第一个分组结果： 010</span></span><br><span class="line"><span class="string">获取第二个分组结果： 1234567</span></span><br><span class="line"><span class="string">使用groups():  (&#x27;010&#x27;, &#x27;1234567&#x27;)</span></span><br><span class="line"><span class="string">获取第一个分组结果： 010</span></span><br><span class="line"><span class="string">获取第二个分组结果： 1234567</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">&lt;re.Match object; span=(0, 31), match=&#x27;&lt;html&gt;&lt;head&gt;分组的使用&lt;/head&gt;&lt;/html&gt;&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>使用分组要了解如下几点：</p>
<ol>
<li>只有圆括号括起来的部分才算一组，如果模式字符串中既有圆括号括起来的部分，也有没有被圆括号括起来的部分，那么只会将被圆括号括起来的部分算作一组，其它的部分忽略。</li>
<li>用<code>group</code>方法获取指定组的值时，组从1开始，也就是说，<code>group(1)</code>获取第1组的值，<code>group(2)</code>获取第2组的值，以此类推。</li>
<li><code>groups</code>方法用于获取所有组的值，以<strong>元组</strong>形式返回。所以除了使用group(1)获取第1组的值外，还可以使用<code>groups()[0]</code>获取第1组的值。<code>groups()[1]</code>获取第2组以及其它组的值的方式类似。</li>
</ol>
<h3 id="re模块中其他常用的函数"><a href="#re模块中其他常用的函数" class="headerlink" title="re模块中其他常用的函数"></a>re模块中其他常用的函数</h3><h4 id="sub和subn搜索与替换"><a href="#sub和subn搜索与替换" class="headerlink" title="sub和subn搜索与替换"></a>sub和subn搜索与替换</h4><p>sub函数和subn函数用于实现搜索和替换功能。这两个函数的功能几乎完全相同，都是将某个字符串中所有匹配正则表达式的部分替</p>
<p>换成其他字符串。用来替换的部分可能是一个字符串，也可以是一个函数，该函数返回一个用来替换的字符串。<strong>sub函数返回替换后</strong></p>
<p><strong>的结果，subn函数返回一个元组，元组的第1个元素是替换后的结果</strong>，第2个元素是替换的总数。语法格式如下：</p>
<p><code>re.sub(pattern, repl, string, count=0,flags=0)</code></p>
<div class="table-container">
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>匹配的正则表达式</td>
</tr>
<tr>
<td>repl</td>
<td>替换的字符串，也可以是一个函数</td>
</tr>
<tr>
<td>string</td>
<td>要被查找替换的原始字符串</td>
</tr>
<tr>
<td>count</td>
<td>模式匹配后替换的最大次数，默认0表示替换所有的匹配</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># sub和subn</span></span><br><span class="line">phone = <span class="string">&quot;2004-959-559 # 这是一个国外电话号码&quot;</span></span><br><span class="line"><span class="comment"># 替换目标字符串中的注释</span></span><br><span class="line">pattern = <span class="string">&quot;#.*&quot;</span></span><br><span class="line">result = re.sub(pattern, <span class="string">&quot;&quot;</span>, phone)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="comment"># 删除非数字的字符串 \D</span></span><br><span class="line">pattern = <span class="string">&quot;\D&quot;</span></span><br><span class="line">result = re.sub(pattern, <span class="string">&quot;&quot;</span>, phone)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="comment"># 调用subn</span></span><br><span class="line">result = re.subn(pattern, <span class="string">&quot;&quot;</span>, phone)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;替换的结果：&quot;</span>, result[<span class="number">0</span>])</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;替换的次数：&quot;</span>, result[<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">2004-959-559 </span></span><br><span class="line"><span class="string">2004959559</span></span><br><span class="line"><span class="string">(&#x27;2004959559&#x27;, 15)</span></span><br><span class="line"><span class="string">替换的结果： 2004959559</span></span><br><span class="line"><span class="string">替换的次数： 15</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="compile函数"><a href="#compile函数" class="headerlink" title="compile函数"></a>compile函数</h4><p>compile 函数用于编译正则表达式，生成一个正则表达式（Pattern）对象，供 <code>match()</code> 和 <code>search()</code> 这两个函数使用。语法格式为：</p>
<p><code>re.compile(pattern[, flags])</code></p>
<div class="table-container">
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>一个字符串形式的正则表达式</td>
</tr>
<tr>
<td>flags</td>
<td>可选，表示匹配模式，比如忽略大小写，多行模式等</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># compile函数的使用</span></span><br><span class="line">s = <span class="string">&#x27;first123 line&#x27;</span></span><br><span class="line">pattern = <span class="string">r&#x27;\w+&#x27;</span></span><br><span class="line">regex = re.<span class="built_in">compile</span>(pattern)  <span class="comment"># 匹配至少一个字母或数字</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;使用compile函数:&quot;</span>, regex.<span class="keyword">match</span>(s))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;直接使用re.match:&quot;</span>, re.<span class="keyword">match</span>(pattern, s))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">使用compile函数: &lt;re.Match object; span=(0, 8), match=&#x27;first123&#x27;&gt;</span></span><br><span class="line"><span class="string">直接使用re.match: &lt;re.Match object; span=(0, 8), match=&#x27;first123&#x27;&gt;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="findall函数"><a href="#findall函数" class="headerlink" title="findall函数"></a>findall函数</h4><p>在字符串中找到正则表达式所匹配的所有子串，并返回一个列表，如果没有找到匹配的，则返回空列表。语法格式如下：</p>
<p><code>findall(pattern, string, flags=0)</code></p>
<div class="table-container">
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>匹配的正则表达式</td>
</tr>
<tr>
<td>string</td>
<td>要匹配的字符串</td>
</tr>
<tr>
<td>flags</td>
<td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。如下表列出正则表达式修饰符 - 可选标志</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># findall 函数的使用</span></span><br><span class="line">pattern = <span class="string">r&#x27;\w+&#x27;</span></span><br><span class="line">s = <span class="string">&#x27;first 1 second 2 third 3 _ $$&#x27;</span></span><br><span class="line">o = re.findall(pattern, s)</span><br><span class="line"><span class="built_in">print</span>(o)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[&#x27;first&#x27;, &#x27;1&#x27;, &#x27;second&#x27;, &#x27;2&#x27;, &#x27;third&#x27;, &#x27;3&#x27;, &#x27;_&#x27;]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>:warning:<strong>注意：</strong></p>
<p>match 和 search 是匹配一次, findall 匹配所有</p>
</blockquote>
<h4 id="finditer函数"><a href="#finditer函数" class="headerlink" title="finditer函数"></a>finditer函数</h4><p>和 findall 类似，在字符串中找到正则表达式所匹配的所有子串，并把它们作为一个迭代器返回。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># finditer函数的使用</span></span><br><span class="line">pattern = <span class="string">r&#x27;\w+&#x27;</span></span><br><span class="line">s = <span class="string">&#x27;first 1 second 2 third 3 _ $$&#x27;</span></span><br><span class="line">o = re.finditer(pattern, s)</span><br><span class="line"><span class="built_in">print</span>(o)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> o:</span><br><span class="line">    <span class="built_in">print</span>(i.group())</span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;callable_iterator object at 0x000002598770DE50&gt;</span></span><br><span class="line"><span class="string">first</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">second</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">third</span></span><br><span class="line"><span class="string">3</span></span><br><span class="line"><span class="string">_</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="split函数"><a href="#split函数" class="headerlink" title="split函数"></a>split函数</h4><p>split函数用于根据正则表达式分隔字符串，也就是说，将字符串与模式匹配的子字符串都作为分隔符来分隔这个字符串。split函数返</p>
<p>回一个列表形式的分隔结果，每一个列表元素都是分隔的子字符串。语法格式如下：</p>
<p><code>re.split(pattern, string[, maxsplit=0,flags=0])</code></p>
<div class="table-container">
<table>
<thead>
<tr>
<th>数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>pattern</td>
<td>匹配的正则表达式</td>
</tr>
<tr>
<td>string</td>
<td>要匹配的字符串</td>
</tr>
<tr>
<td>maxsplit</td>
<td>分隔次数，maxsplit=1 分隔一次，默认为 0，不限制次数。</td>
</tr>
<tr>
<td>flags</td>
<td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># split函数的使用</span></span><br><span class="line">pattern = <span class="string">r&#x27;\d+&#x27;</span></span><br><span class="line">s = <span class="string">&#x27;a 1 b 2 c 3 d&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(re.split(pattern, s))</span><br><span class="line"><span class="comment"># maxsplit 参数限定分隔的次数，这里限定为1，也就是只分隔一次</span></span><br><span class="line"><span class="built_in">print</span>(re.split(pattern, s, maxsplit=<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">[&#x27;a &#x27;, &#x27; b &#x27;, &#x27; c &#x27;, &#x27; d&#x27;]</span></span><br><span class="line"><span class="string">[&#x27;a &#x27;, &#x27; b 2 c 3 d&#x27;]</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="贪婪模式和非贪婪模式"><a href="#贪婪模式和非贪婪模式" class="headerlink" title="贪婪模式和非贪婪模式"></a>贪婪模式和非贪婪模式</h3><p><strong>贪婪模式</strong>指Python里数量词默认是贪婪的，总是尝试<strong>匹配尽可能多的字符</strong>。<strong>非贪婪模式</strong>与贪婪相反，总是尝试<strong>匹配尽可能少的字符</strong>，</p>
<p>可以使用<code>*</code>，<code>?</code>，<code>+</code>，<code>&#123;m,n&#125;</code>后面加上<code>?</code>，使贪婪变成非贪婪。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line">s = <span class="string">&quot;This is mytel:133-1234-1234&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;----------贪婪模式---------&#x27;</span>)</span><br><span class="line">pattern = <span class="string">r&quot;(.+)(\d+-\d+-\d+)&quot;</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, s)</span><br><span class="line"><span class="built_in">print</span>(result.group())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;第一个分组匹配结果：&quot;</span>, result.group(<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;第二个分组匹配结果：&quot;</span>, result.group(<span class="number">2</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;----------非贪婪模式---------&#x27;</span>)</span><br><span class="line">pattern = <span class="string">r&quot;(.+?)(\d+-\d+-\d+)&quot;</span></span><br><span class="line">result = re.<span class="keyword">match</span>(pattern, s)</span><br><span class="line"><span class="built_in">print</span>(result.group())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;第一个分组匹配结果：&quot;</span>, result.group(<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;第二个分组匹配结果：&quot;</span>, result.group(<span class="number">2</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;-------------------------------&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;贪婪模式&#x27;</span>)</span><br><span class="line">s = <span class="string">&quot;abc123&quot;</span></span><br><span class="line">v = re.<span class="keyword">match</span>(<span class="string">r&#x27;abc(\d+)&#x27;</span>, <span class="string">&#x27;abc123&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(v.group(<span class="number">1</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;非贪婪模式&#x27;</span>)</span><br><span class="line">v = re.<span class="keyword">match</span>(<span class="string">r&#x27;abc(\d+?)&#x27;</span>, <span class="string">&#x27;abc123&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(v.group(<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">----------贪婪模式---------</span></span><br><span class="line"><span class="string">This is mytel:133-1234-1234</span></span><br><span class="line"><span class="string">第一个分组匹配结果： This is mytel:13</span></span><br><span class="line"><span class="string">第二个分组匹配结果： 3-1234-1234</span></span><br><span class="line"><span class="string">----------非贪婪模式---------</span></span><br><span class="line"><span class="string">This is mytel:133-1234-1234</span></span><br><span class="line"><span class="string">第一个分组匹配结果： This is mytel:</span></span><br><span class="line"><span class="string">第二个分组匹配结果： 133-1234-1234</span></span><br><span class="line"><span class="string">-------------------------------</span></span><br><span class="line"><span class="string">贪婪模式</span></span><br><span class="line"><span class="string">123</span></span><br><span class="line"><span class="string">非贪婪模式</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h2 id="Python新特性"><a href="#Python新特性" class="headerlink" title="Python新特性"></a>Python新特性</h2><h3 id="formatted字符串字面值"><a href="#formatted字符串字面值" class="headerlink" title="formatted字符串字面值"></a>formatted字符串字面值</h3><p>formatted字符串是带有<code>f</code>字符前缀的字符串，可以很方便的格式化字符串</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line">name = <span class="string">&quot;jhon&quot;</span></span><br><span class="line">age = <span class="number">20</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;name: %s, age: %d&quot;</span> % (name, age))</span><br><span class="line"><span class="comment"># 使用format</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;name: &#123;&#125;, age: &#123;&#125;&quot;</span>.<span class="built_in">format</span>(name, age))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;name: <span class="subst">&#123;name&#125;</span>, age: <span class="subst">&#123;age&#125;</span>&quot;</span>)</span><br><span class="line">names = [<span class="string">&quot;java&quot;</span>, <span class="string">&quot;python&quot;</span>, <span class="string">&quot;c++&quot;</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;name1: <span class="subst">&#123;names[<span class="number">0</span>]&#125;</span>, name2: <span class="subst">&#123;names[<span class="number">1</span>]&#125;</span>, name3: <span class="subst">&#123;names[<span class="number">2</span>]&#125;</span>&quot;</span>)</span><br><span class="line"><span class="comment"># 表达式</span></span><br><span class="line">a = <span class="number">10</span></span><br><span class="line">b = <span class="number">20</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;a+b运算: <span class="subst">&#123;a + b&#125;</span>&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;表达式运算的结果：<span class="subst">&#123;<span class="number">3</span> * (a + b)&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">name: jhon, age: 20</span></span><br><span class="line"><span class="string">name: jhon, age: 20</span></span><br><span class="line"><span class="string">name: jhon, age: 20</span></span><br><span class="line"><span class="string">name1: java, name2: python, name3: c++</span></span><br><span class="line"><span class="string">a+b运算: 30</span></span><br><span class="line"><span class="string">表达式运算的结果：90</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="formatted字符串支持"><a href="#formatted字符串支持" class="headerlink" title="formatted字符串支持 ="></a>formatted字符串支持 <code>=</code></h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># formatted字符串支持 =</span></span><br><span class="line">a = <span class="number">10</span></span><br><span class="line">b = <span class="number">20</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;a=&#125;</span>, <span class="subst">&#123;b=&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用指定的字符填充</span></span><br><span class="line"><span class="comment"># 使用 * 居中填充</span></span><br><span class="line">name = <span class="string">&quot;jhon&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;&#123;:*^20&#125;&quot;</span>.<span class="built_in">format</span>(name))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name:*^<span class="number">20</span>&#125;</span>&quot;</span>)</span><br><span class="line"><span class="comment"># 使用 * 居右填充</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name:*&gt;<span class="number">20</span>&#125;</span>&quot;</span>)</span><br><span class="line"><span class="comment"># 使用 * 居左填充</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name:*&lt;<span class="number">20</span>&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 对数值变量的格式化</span></span><br><span class="line">price = <span class="number">12.235</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;&#123;:.2f&#125;&quot;</span>.<span class="built_in">format</span>(price))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;price:<span class="number">.2</span>f&#125;</span>&quot;</span>)</span><br><span class="line">num = <span class="number">12</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;num=:<span class="number">.1</span>f&#125;</span>&quot;</span>)</span><br><span class="line">pct = <span class="number">0.789</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;&#123;:.2f&#125;%&quot;</span>.<span class="built_in">format</span>(pct*<span class="number">100</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;pct*<span class="number">100</span>:<span class="number">.0</span>f&#125;</span>%&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">a=10, b=20</span></span><br><span class="line"><span class="string">*******jhon********</span></span><br><span class="line"><span class="string">********jhon********</span></span><br><span class="line"><span class="string">****************jhon</span></span><br><span class="line"><span class="string">jhon****************</span></span><br><span class="line"><span class="string">12.23</span></span><br><span class="line"><span class="string">12.23</span></span><br><span class="line"><span class="string">num=12.0</span></span><br><span class="line"><span class="string">78.90%</span></span><br><span class="line"><span class="string">79%</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="字符串新方法"><a href="#字符串新方法" class="headerlink" title="字符串新方法"></a>字符串新方法</h3><div class="table-container">
<table>
<thead>
<tr>
<th>方法名</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>str.removeprefix()</code></td>
<td>如果str以它开头的话，将会返回一个修改过前缀的新字符串，否则它将返回原始字符串</td>
</tr>
<tr>
<td><code>str.removesuffix()</code></td>
<td>如果str以其结尾，则返回带有修改过后缀的新字符串，否则它将返回原始字符串</td>
</tr>
</tbody>
</table>
</div>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line">info = <span class="string">&#x27;helloworld&#x27;</span></span><br><span class="line"><span class="comment"># 删除前缀</span></span><br><span class="line"><span class="built_in">print</span>(info.removeprefix(<span class="string">&#x27;hello&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(info.removeprefix(<span class="string">&#x27;abc&#x27;</span>))</span><br><span class="line"><span class="comment"># 删除后缀</span></span><br><span class="line"><span class="built_in">print</span>(info.removesuffix(<span class="string">&#x27;world&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(info.removesuffix(<span class="string">&#x27;World&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">world</span></span><br><span class="line"><span class="string">helloworld</span></span><br><span class="line"><span class="string">hello</span></span><br><span class="line"><span class="string">helloworld</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="变量类型标注"><a href="#变量类型标注" class="headerlink" title="变量类型标注"></a>变量类型标注</h3><p>变量类型注解是用来对变量和函数的参数返回值类型做注解（暗示），帮助开发者写出更加严谨的代码，让调用方减少类型方面的错误，也可以提高代码的可读性和易用性。</p>
<p>但是，变量类型注解语法传入的类型表述能力有限，不能说明复杂的类型组成情况，因此引入了 <code>typing</code> 模块，来实现复杂的类型表达。</p>
<h4 id="常用的数据类型"><a href="#常用的数据类型" class="headerlink" title="常用的数据类型"></a>常用的数据类型</h4><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191852214.png" alt="image-20240112185445452"></p>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191852080.png" alt="image-20240112185500423"></p>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li>mypy是Python的可选静态类型检查器</li>
<li>安装mypy模块</li>
<li>使用mypy进行静态类型检查 mypy 执行python文件</li>
</ul>
</blockquote>
<h4 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 简化变量类型标注</span></span><br><span class="line">a: <span class="built_in">int</span> = <span class="number">10</span></span><br><span class="line">b: <span class="built_in">str</span> = <span class="string">&quot;hello&quot;</span></span><br><span class="line">c: <span class="built_in">float</span> = <span class="number">3.14</span></span><br><span class="line">d: <span class="built_in">bool</span> = <span class="literal">True</span></span><br><span class="line">e: <span class="built_in">bytes</span> = <span class="string">b&quot;world&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 复杂类型</span></span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">List</span>, <span class="type">Set</span>, <span class="type">Dict</span>, <span class="type">Tuple</span></span><br><span class="line"></span><br><span class="line">x: <span class="type">List</span>[<span class="built_in">int</span>] = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">y: <span class="type">Set</span>[<span class="built_in">str</span>] = &#123;<span class="string">&quot;ab&quot;</span>, <span class="string">&quot;cd&quot;</span>&#125;</span><br><span class="line">z: <span class="type">Dict</span>[<span class="built_in">str</span>, <span class="built_in">str</span>] = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;jhon&quot;</span>, <span class="string">&quot;sex&quot;</span>: <span class="string">&quot;male&quot;</span>&#125;</span><br><span class="line">h: <span class="type">Dict</span>[<span class="built_in">str</span>, <span class="built_in">object</span>] = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;jhon&quot;</span>, <span class="string">&quot;sex&quot;</span>: <span class="string">&quot;male&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">20</span>&#125;</span><br><span class="line">j: <span class="type">Tuple</span>[<span class="built_in">int</span>] = (<span class="number">3</span>,)</span><br><span class="line">k: <span class="type">Tuple</span>[<span class="built_in">int</span>, <span class="built_in">int</span>, <span class="built_in">int</span>] = (<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)</span><br><span class="line">l: <span class="type">Tuple</span>[<span class="built_in">int</span>, <span class="built_in">str</span>, <span class="built_in">float</span>] = (<span class="number">3</span>, <span class="string">&quot;name&quot;</span>, <span class="number">5.1</span>)</span><br><span class="line"><span class="comment"># 定义可变大小的元组，使用省略号</span></span><br><span class="line">m: <span class="type">Tuple</span>[<span class="built_in">int</span>, ...] = (<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)</span><br></pre></td></tr></table></figure>
<h4 id="简化变量类型标注"><a href="#简化变量类型标注" class="headerlink" title="简化变量类型标注"></a>简化变量类型标注</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 3.10新特性可以直接使用 list,tuple,dict,set</span></span><br><span class="line">n: <span class="built_in">list</span>[<span class="built_in">str</span>] = [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]</span><br><span class="line">q: <span class="built_in">tuple</span>[<span class="built_in">int</span>] = (<span class="number">2</span>,)</span><br><span class="line">p: <span class="built_in">tuple</span>[<span class="built_in">int</span>, <span class="built_in">int</span>] = (<span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"><span class="comment"># 定义可变大小的元组，使用省略号</span></span><br><span class="line">i: <span class="built_in">tuple</span>[<span class="built_in">int</span>, ...] = (<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)</span><br><span class="line">f: <span class="built_in">set</span>[<span class="built_in">str</span>] = &#123;<span class="string">&quot;aa&quot;</span>, <span class="string">&quot;bb&quot;</span>, <span class="string">&quot;cc&quot;</span>&#125;</span><br><span class="line">u: <span class="built_in">dict</span>[<span class="built_in">str</span>, <span class="built_in">object</span>] = &#123;<span class="string">&quot;k1&quot;</span>: <span class="number">1</span>, <span class="string">&quot;k2&quot;</span>: <span class="string">&quot;aa&quot;</span>, <span class="string">&quot;k3&quot;</span>: <span class="literal">True</span>&#125;</span><br></pre></td></tr></table></figure>
<h4 id="函数参数返回值添加类型标注"><a href="#函数参数返回值添加类型标注" class="headerlink" title="函数参数返回值添加类型标注"></a>函数参数返回值添加类型标注</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 定义一个函数</span></span><br><span class="line"><span class="comment"># 参数 num：int类型</span></span><br><span class="line"><span class="comment"># 返回值：str类型</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">num_fun</span>(<span class="params">num: <span class="built_in">int</span></span>) -&gt; <span class="built_in">str</span>:</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">str</span>(num)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义一个函数，两个参数都是int，返回int</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sun_fun</span>(<span class="params">a: <span class="built_in">int</span>, b: <span class="built_in">int</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">return</span> a + b</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义一个函数，参数添加默认值</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fun_test</span>(<span class="params">num1: <span class="built_in">int</span>, num2: <span class="built_in">float</span> = <span class="number">12.34</span></span>) -&gt; <span class="built_in">float</span>:</span><br><span class="line">    <span class="keyword">return</span> num1 + num2</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(fun_test(<span class="number">10</span>, <span class="number">29</span>))  <span class="comment"># 30</span></span><br><span class="line"><span class="built_in">print</span>(fun_test(<span class="number">10</span>))  <span class="comment"># 22.34</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义一个变量指向函数</span></span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">Callable</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Callable[[参数类型, 参数类型], 返回值类型]</span></span><br><span class="line">f: <span class="type">Callable</span>[[<span class="built_in">int</span>, <span class="built_in">int</span>], <span class="built_in">int</span>] = sun_fun</span><br><span class="line"><span class="built_in">print</span>(f(<span class="number">10</span>, <span class="number">20</span>))  <span class="comment"># 30</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义函数，产生整数的生成器，每次返回一个</span></span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> Iterable</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">return_fun</span>(<span class="params">num: <span class="built_in">int</span></span>) -&gt; Iterable[<span class="built_in">int</span>]:</span><br><span class="line">    i = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> i &lt; num:</span><br><span class="line">        <span class="keyword">yield</span> i</span><br><span class="line">        i += <span class="number">1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(return_fun(<span class="number">10</span>))   <span class="comment"># &lt;generator object return_fun at 0x00000241595FC430&gt;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> return_fun(<span class="number">10</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line">    </span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">0</span></span><br><span class="line"><span class="string">1</span></span><br><span class="line"><span class="string">2</span></span><br><span class="line"><span class="string">3</span></span><br><span class="line"><span class="string">4</span></span><br><span class="line"><span class="string">5</span></span><br><span class="line"><span class="string">6</span></span><br><span class="line"><span class="string">7</span></span><br><span class="line"><span class="string">8</span></span><br><span class="line"><span class="string">9</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="混合类型检查改进"><a href="#混合类型检查改进" class="headerlink" title="混合类型检查改进"></a>混合类型检查改进</h4><p>联合运算符使用<code>|</code>线来代替了旧版本中<code>Union[]</code>方法，使得程序更加简洁。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> <span class="type">Union</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">oldFunc</span>(<span class="params">para: <span class="type">Union</span>[<span class="built_in">int</span>, <span class="built_in">float</span>]</span>) -&gt; <span class="type">Union</span>[<span class="built_in">int</span>, <span class="built_in">float</span>]:</span><br><span class="line">    <span class="keyword">return</span> para ** <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用</span></span><br><span class="line">oldFunc(<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">newFunc</span>(<span class="params">para: <span class="built_in">int</span> | <span class="built_in">float</span></span>) -&gt; <span class="built_in">int</span> | <span class="built_in">float</span>:</span><br><span class="line">    <span class="keyword">return</span> para + <span class="number">10</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用</span></span><br><span class="line"><span class="built_in">print</span>(newFunc(<span class="number">10</span>))</span><br><span class="line"><span class="built_in">print</span>(newFunc(<span class="number">10.10</span>))</span><br></pre></td></tr></table></figure>
<h4 id="类型别名更改"><a href="#类型别名更改" class="headerlink" title="类型别名更改"></a>类型别名更改</h4><p>之前是直接通过不同类型的赋值操作来赋予类型新的名字，在新版本中通过<code>TypeAlias</code>来规定了类型名字的替换。这样操作的优势在于能够让程序开发人员和Python编辑器更加清楚的知道newname是一个变量名还是一个类型的别名，提升程序开发的可靠性。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line">oldname = <span class="built_in">str</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">oldFunc</span>(<span class="params">param: oldname</span>) -&gt; oldname:</span><br><span class="line">    <span class="keyword">return</span> param + param</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">oldFunc(<span class="string">&#x27;oldFunc:百战程序员&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> TypeAlias</span><br><span class="line"></span><br><span class="line">newstr: TypeAlias = <span class="built_in">str</span></span><br><span class="line">newint: TypeAlias = <span class="built_in">int</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">newFunc</span>(<span class="params">num: newint, msg: newstr</span>) -&gt; newstr:</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">str</span>(num) + msg</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(newFunc(<span class="number">100</span>, <span class="string">&quot;类型别名更改&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">100类型别名更改</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="二进制表示频率为1的数量统计"><a href="#二进制表示频率为1的数量统计" class="headerlink" title="二进制表示频率为1的数量统计"></a>二进制表示频率为1的数量统计</h3><p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191852931.png" alt="image-20240113170649031"></p>
<p>通过调用<code>bit_count</code>函数来统计二进制中数字“1”的个数</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># bit_count()函数</span></span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line">value = <span class="number">5</span></span><br><span class="line"><span class="comment"># bin()转化为二进制</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">bin</span>(value))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;出现1的次数：&quot;</span>, <span class="built_in">bin</span>(value).count(<span class="string">&quot;1&quot;</span>))</span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;出现1的次数：&quot;</span>, value.bit_count())</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">0b101</span></span><br><span class="line"><span class="string">出现1的次数： 2</span></span><br><span class="line"><span class="string">出现1的次数： 2</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="字典的三个方法新增mapping属性"><a href="#字典的三个方法新增mapping属性" class="headerlink" title="字典的三个方法新增mapping属性"></a>字典的三个方法新增mapping属性</h3><p>在Python 3.10中，针对于字典的三个方法，<code>items</code>，<code>keys</code>，和<code>values</code>都增加了一个<code>mapping</code>属性，通过下面的程序可以发现，对三个方法调用<code>mapping</code>属性后都会<strong>返回原字典数据</strong>。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line">mydict = &#123;<span class="string">&quot;一&quot;</span>: <span class="number">1</span>, <span class="string">&quot;二&quot;</span>: <span class="number">2</span>, <span class="string">&quot;三&quot;</span>: <span class="number">3</span>&#125;</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;字典数据：&quot;</span>, mydict)</span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line"><span class="built_in">print</span>(mydict.keys(), mydict.values(), mydict.items())</span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line">keys = mydict.keys()</span><br><span class="line">values = mydict.values()</span><br><span class="line">items = mydict.items()</span><br><span class="line"><span class="built_in">print</span>(keys.mapping, values.mapping, items.mapping)</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">字典数据： &#123;&#x27;一&#x27;: 1, &#x27;二&#x27;: 2, &#x27;三&#x27;: 3&#125;</span></span><br><span class="line"><span class="string">dict_keys([&#x27;一&#x27;, &#x27;二&#x27;, &#x27;三&#x27;]) dict_values([1, 2, 3]) dict_items([(&#x27;一&#x27;, 1), (&#x27;二&#x27;, 2), (&#x27;三&#x27;, 3)])</span></span><br><span class="line"><span class="string">&#123;&#x27;一&#x27;: 1, &#x27;二&#x27;: 2, &#x27;三&#x27;: 3&#125; &#123;&#x27;一&#x27;: 1, &#x27;二&#x27;: 2, &#x27;三&#x27;: 3&#125; &#123;&#x27;一&#x27;: 1, &#x27;二&#x27;: 2, &#x27;三&#x27;: 3&#125;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="函数zip-新增strict参数"><a href="#函数zip-新增strict参数" class="headerlink" title="函数zip()新增strict参数"></a>函数zip()新增strict参数</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line">keys = [<span class="string">&quot;name&quot;</span>, <span class="string">&quot;age&quot;</span>, <span class="string">&quot;sex&quot;</span>]</span><br><span class="line">values = [<span class="string">&quot;jhon&quot;</span>, <span class="number">23</span>, <span class="string">&quot;man&quot;</span>, <span class="number">12</span>, <span class="string">&quot;nan&quot;</span>]</span><br><span class="line">data_dict = <span class="built_in">dict</span>(<span class="built_in">zip</span>(keys, values))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;创建的字典对象：&quot;</span>, data_dict)</span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line">data_dict2 = <span class="built_in">dict</span>(<span class="built_in">zip</span>(keys, values, strict=<span class="literal">True</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;新版本添加strict属性：&quot;</span>, data_dict2)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">创建的字典对象： &#123;&#x27;name&#x27;: &#x27;jhon&#x27;, &#x27;age&#x27;: 23, &#x27;sex&#x27;: &#x27;man&#x27;&#125;</span></span><br><span class="line"><span class="string">Traceback (most recent call last):</span></span><br><span class="line"><span class="string">  File &quot;D:\2022百战Python\函数式编程和核心特性\python新特性\函数zip()新增strict参数.py&quot;, line 8, in &lt;module&gt;</span></span><br><span class="line"><span class="string">    data_dict2 = dict(zip(keys,values,strict=True))</span></span><br><span class="line"><span class="string">ValueError: zip() argument 2 is longer than argument 1</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>对于<code>zip</code>函数加了<code>strict</code>参数，顾名思义<code>strict</code>参数就是要严格的通过参数长度的匹配原则，在以上代码中，<code>keys</code>和<code>values</code>列表的长度并不一致。旧版本的<code>zip</code>函数会根据长度最短的参数创建字典。新版本的<code>zip</code>函数中，当设定<code>strict</code>参数为<code>True</code>，则要求<code>zip</code>的输入数必须要长度一致，否则报错。</p>
<h3 id="dataclass"><a href="#dataclass" class="headerlink" title="dataclass"></a>dataclass</h3><h4 id="使用类"><a href="#使用类" class="headerlink" title="使用类"></a>使用类</h4><p>为了支持数据修改, 默认值, 比较等功能。更加好一些的方法是：使用自定义类来实现数据类。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Player</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,name:<span class="built_in">str</span>,number:<span class="built_in">int</span>,postion:<span class="built_in">str</span>,age:<span class="built_in">int</span> = <span class="number">18</span></span>) -&gt; <span class="literal">None</span>:</span><br><span class="line">        self.name = name</span><br><span class="line">        self.number = number</span><br><span class="line">        self.postion = postion</span><br><span class="line">        self.age = age</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__repr__</span>(<span class="params">self</span>) -&gt; <span class="built_in">str</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;Player: <span class="subst">&#123;self.name&#125;</span> <span class="subst">&#123;self.number&#125;</span>&#x27;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self, __o: <span class="built_in">object</span></span>) -&gt; <span class="built_in">bool</span>:</span><br><span class="line">        <span class="keyword">return</span> self.age == __o.age</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__gt__</span>(<span class="params">self,__o: <span class="built_in">object</span></span>) -&gt;<span class="built_in">bool</span>:</span><br><span class="line">        <span class="keyword">return</span> self.age &gt; __o.age</span><br><span class="line">    </span><br><span class="line">p1 = Player(<span class="string">&#x27;SXT&#x27;</span>,<span class="number">18</span>,<span class="string">&#x27;PG&#x27;</span>,<span class="number">26</span>)</span><br><span class="line"><span class="built_in">print</span>(p1)</span><br></pre></td></tr></table></figure>
<blockquote>
<p><strong>缺点</strong></p>
<ul>
<li><code>__init__</code> 方法中重复代码 (示例中每个属性都需要写3遍)</li>
<li>需要自己实现 <code>__repr__</code> 方法, 和比较方法 <code>__eq__</code> , <code>__gt__</code> 等</li>
</ul>
</blockquote>
<h4 id="使用dataclass"><a href="#使用dataclass" class="headerlink" title="使用dataclass"></a>使用dataclass</h4><p><code>dataclass</code> 可以认为是提供了一个简写 <code>__init__</code> 方法的语法糖，类型注释是必填项 (不限制数据类型时, 添加<code>typing.Any</code>为类型注释)，默认值的传递方式和 <code>__init__</code> 方法的参数格式一致。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> dataclasses <span class="keyword">import</span> dataclass</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@dataclass</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Player</span>:</span><br><span class="line">    name: <span class="built_in">str</span></span><br><span class="line">    postion: <span class="built_in">str</span></span><br><span class="line">    age: <span class="built_in">int</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建实例对象</span></span><br><span class="line">p = Player(<span class="string">&quot;jhon&quot;</span>, <span class="string">&quot;beijing&quot;</span>, <span class="number">21</span>)</span><br><span class="line"><span class="built_in">print</span>(p)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">Player(name=&#x27;jhon&#x27;, postion=&#x27;beijing&#x27;, age=21)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p><strong>优点</strong></p>
<p>可以使用 dataclasses 模块中的其它方法，比如：</p>
<ul>
<li>转为字典 asdict</li>
<li>转为元组 astuple</li>
</ul>
</blockquote>
<h5 id="dataclass装饰器上的参数"><a href="#dataclass装饰器上的参数" class="headerlink" title="dataclass装饰器上的参数"></a>dataclass装饰器上的参数</h5><p><code>dataclass</code> 装饰器将根据类属性生成数据类和数据类需要的方法。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dataclasses.dataclass(*, init = <span class="literal">True</span>, <span class="built_in">repr</span> = <span class="literal">True</span>, eq = <span class="literal">True</span>, order = <span class="literal">False</span>, unsafe_hash = <span class="literal">False</span>, frozen = <span class="literal">False</span>)</span><br></pre></td></tr></table></figure>
<p><img src="https://gitee.com/huaiyuechusan/picture/raw/master/Typora/202401191852442.png" alt="image-20240113173132614"></p>
<h5 id="dataclass成员变量额外设置"><a href="#dataclass成员变量额外设置" class="headerlink" title="dataclass成员变量额外设置"></a>dataclass成员变量额外设置</h5><p>可以通过 <code>dataclass.filed</code> 方法设置变量的额外功能</p>
<ol>
<li><p><code>defualt</code>:设置默认值</p>
<p>值为具体的值</p>
</li>
<li><p><code>default_factory</code>:设置默认值</p>
<p>值为类型名，程序会根据类型名创建一个空的对象，若使用<code>defualt</code>设置需要手动创建空对象</p>
</li>
<li><p><code>repr</code>设置生成的 <code>__repr__</code> 方法中是否加入此属性，默认是<code>True</code></p>
</li>
</ol>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> dataclasses <span class="keyword">import</span> dataclass, field</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@dataclass</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Player</span>:</span><br><span class="line">    name: <span class="built_in">str</span></span><br><span class="line">    postion: <span class="built_in">str</span></span><br><span class="line">    age: <span class="built_in">int</span></span><br><span class="line">    sex: <span class="built_in">str</span> = field(default=<span class="string">&quot;man&quot;</span>, <span class="built_in">repr</span>=<span class="literal">False</span>)</span><br><span class="line">    <span class="comment"># msg: str = field(default=&quot;&quot;)</span></span><br><span class="line">    <span class="comment"># 创建空对象</span></span><br><span class="line">    msg: <span class="built_in">str</span> = field(default_factory=<span class="built_in">str</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建实例对象</span></span><br><span class="line">p = Player(<span class="string">&quot;jhon&quot;</span>, <span class="string">&quot;beijing&quot;</span>, <span class="number">21</span>)</span><br><span class="line"><span class="built_in">print</span>(p)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">Player(name=&#x27;jhon&#x27;, postion=&#x27;beijing&#x27;, age=21, msg=&#x27;&#x27;)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h5 id="dataclass建立类变量"><a href="#dataclass建立类变量" class="headerlink" title="dataclass建立类变量"></a>dataclass建立类变量</h5><p>在类中建立变量，默认是成员变量，若需要设置类变量，需要设置类型为： <code>ClassVar</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> dataclasses <span class="keyword">import</span> dataclass, field</span><br><span class="line"><span class="keyword">from</span> typing <span class="keyword">import</span> ClassVar</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@dataclass</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Player</span>:</span><br><span class="line">    name: <span class="built_in">str</span></span><br><span class="line">    postion: <span class="built_in">str</span></span><br><span class="line">    age: <span class="built_in">int</span></span><br><span class="line">    sex: <span class="built_in">str</span> = field(default=<span class="string">&quot;man&quot;</span>, <span class="built_in">repr</span>=<span class="literal">False</span>)</span><br><span class="line">    <span class="comment"># msg: str = field(default=&quot;&quot;)</span></span><br><span class="line">    <span class="comment"># 创建空对象</span></span><br><span class="line">    msg: <span class="built_in">str</span> = field(default_factory=<span class="built_in">str</span>)</span><br><span class="line">    <span class="comment"># 类变量（类属性）</span></span><br><span class="line">    country: ClassVar[<span class="built_in">str</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建实例对象</span></span><br><span class="line">p = Player(<span class="string">&quot;jhon&quot;</span>, <span class="string">&quot;beijing&quot;</span>, <span class="number">21</span>)</span><br><span class="line"><span class="built_in">print</span>(p)</span><br><span class="line">Player.country = <span class="string">&quot;China&quot;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;类属性：&quot;</span>, Player.country)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">Player(name=&#x27;jhon&#x27;, postion=&#x27;beijing&#x27;, age=21, msg=&#x27;&#x27;)</span></span><br><span class="line"><span class="string">类属性： China</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="字典合并"><a href="#字典合并" class="headerlink" title="字典合并"></a>字典合并</h3><p>字典添加两个新的运算符：<code>|</code>和<code>|=</code>。<code>|</code>运算符用于合并字典。<code>|=</code>用于更新字典。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line">dict1 = &#123;<span class="string">&#x27;a&#x27;</span>: <span class="string">&#x27;1&#x27;</span>&#125;</span><br><span class="line">dict2 = &#123;<span class="string">&#x27;b&#x27;</span>: <span class="string">&#x27;2&#x27;</span>&#125;</span><br><span class="line"><span class="comment"># 旧版本</span></span><br><span class="line">dict1.update(dict2)</span><br><span class="line"><span class="built_in">print</span>(dict1)</span><br><span class="line"><span class="comment"># 新版本</span></span><br><span class="line"><span class="comment"># |合并字典</span></span><br><span class="line">dict3 = dict1 | dict2</span><br><span class="line"><span class="built_in">print</span>(dict3)</span><br><span class="line"><span class="comment"># |= 更新字典</span></span><br><span class="line">dict1 |= dict2  <span class="comment"># 等价于 dict1 = dict1 | dict2</span></span><br><span class="line"><span class="built_in">print</span>(dict1)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&#123;&#x27;a&#x27;: &#x27;1&#x27;, &#x27;b&#x27;: &#x27;2&#x27;&#125;</span></span><br><span class="line"><span class="string">&#123;&#x27;a&#x27;: &#x27;1&#x27;, &#x27;b&#x27;: &#x27;2&#x27;&#125;</span></span><br><span class="line"><span class="string">&#123;&#x27;a&#x27;: &#x27;1&#x27;, &#x27;b&#x27;: &#x27;2&#x27;&#125;</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="match语法"><a href="#match语法" class="headerlink" title="match语法"></a>match语法</h3><p><code>match...case</code>结构化模式匹配，可以匹配字典、类以及其他更复杂的结构。<code>match...case</code>的匹配模式匹配于Java或C++中的switch的使用很相似。语法格式如下：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">match</span> subject:</span><br><span class="line">    <span class="keyword">case</span> &lt;pattern_1&gt;:</span><br><span class="line">        &lt;action_1&gt;</span><br><span class="line">    <span class="keyword">case</span> &lt;pattern_2&gt;:</span><br><span class="line">        &lt;action_2&gt;</span><br><span class="line">    <span class="keyword">case</span> &lt;pattern_3&gt;:</span><br><span class="line">        &lt;action_3&gt;</span><br><span class="line">    <span class="keyword">case</span> _:</span><br><span class="line">        &lt;action_wildcard&gt;</span><br></pre></td></tr></table></figure>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line">status = <span class="number">404</span></span><br><span class="line"><span class="keyword">match</span> status:</span><br><span class="line">    <span class="keyword">case</span> <span class="number">200</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;访问成功&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">404</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;访问的资源不存在&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">500</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;服务器错误&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> _:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;以上都没有匹配成功&quot;</span>)</span><br><span class="line"></span><br><span class="line">p1 = (<span class="string">&quot;superman&quot;</span>, <span class="number">23</span>, <span class="string">&quot;man&quot;</span>)</span><br><span class="line">p2 = (<span class="string">&quot;joker&quot;</span>, <span class="number">21</span>, <span class="string">&quot;woman&quot;</span>)</span><br><span class="line">p3 = (<span class="string">&quot;parker&quot;</span>, <span class="number">20</span>, <span class="string">&quot;male&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func_test</span>(<span class="params">person</span>):</span><br><span class="line">    <span class="keyword">match</span> person:</span><br><span class="line">        <span class="keyword">case</span> (name, _, <span class="string">&quot;man&quot;</span>):</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span> is man&quot;</span>)</span><br><span class="line">        <span class="keyword">case</span> (name, _, <span class="string">&quot;woman&quot;</span>):</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span> is woman&quot;</span>)</span><br><span class="line">        <span class="keyword">case</span> (name, age, sex):</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span>, <span class="subst">&#123;age&#125;</span>, <span class="subst">&#123;sex&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用函数</span></span><br><span class="line">func_test(p1)</span><br><span class="line">func_test(p2)</span><br><span class="line">func_test(p3)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">访问的资源不存在</span></span><br><span class="line"><span class="string">superman is man</span></span><br><span class="line"><span class="string">joker is woman</span></span><br><span class="line"><span class="string">parker,20,male</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>上述代码中，<code>case</code>函数通过匹配元组，如果元组第三个参数是<code>female</code>，匹配到第一个<code>case</code>。如果元组第三个参数是<code>male</code>，匹配到第二个<code>case</code>。如果前面两个都不匹配，则输出最后的默认结果。</p>
<h2 id="内存管理"><a href="#内存管理" class="headerlink" title="内存管理"></a>内存管理</h2><h3 id="元类"><a href="#元类" class="headerlink" title="元类"></a>元类</h3><ol>
<li>类也是对象（属于元类的对象）</li>
<li>使用动态创建类：</li>
</ol>
<p>语法：<code>type(类名，由父类名称组成的元组（可以为空），包含属性的字典（名称和值）)</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">元类：</span></span><br><span class="line"><span class="string">    什么是元类？</span></span><br><span class="line"><span class="string">        动态创建类</span></span><br><span class="line"><span class="string">        元类-&gt;类</span></span><br><span class="line"><span class="string">        类-&gt;对象</span></span><br><span class="line"><span class="string">    用途？</span></span><br><span class="line"><span class="string">        可以动态创建类</span></span><br><span class="line"><span class="string">    如何使用？</span></span><br><span class="line"><span class="string">    type()</span></span><br><span class="line"><span class="string">        1.查看目标对象的数据类型</span></span><br><span class="line"><span class="string">        2.可以使用type，动态创建类</span></span><br><span class="line"><span class="string">        语法:</span></span><br><span class="line"><span class="string">            类 = type(类名,(父类...),&#123;属性，方法&#125;)</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 创建一个默认父类，不包含任何属性方法的类</span></span><br><span class="line">Person = <span class="built_in">type</span>(<span class="string">&#x27;Person&#x27;</span>, (), &#123;&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否可以用Person创建对象</span></span><br><span class="line">p1 = Person()</span><br><span class="line"><span class="built_in">print</span>(p1)</span><br><span class="line"><span class="comment"># mro()   父类是object</span></span><br><span class="line"><span class="built_in">print</span>(Person.mro())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 传统静态方式创建类</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color</span>):</span><br><span class="line">        self.color = color</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">eat</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;动物需要吃东西&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sleep</span>(<span class="params">self</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;狗狗趴着睡觉&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用type动态创建一个类，父类就是Animal</span></span><br><span class="line">Dog = <span class="built_in">type</span>(<span class="string">&#x27;Dog&#x27;</span>, (Animal,), &#123;<span class="string">&#x27;age&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;sleep&#x27;</span>: sleep&#125;)</span><br><span class="line">dog = Dog(<span class="string">&#x27;Yellow&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(dog.age)</span><br><span class="line">dog.sleep()</span><br><span class="line"><span class="comment"># 是否继承了父类中的特性</span></span><br><span class="line"><span class="comment"># 父类中的属性</span></span><br><span class="line"><span class="built_in">print</span>(dog.color)</span><br><span class="line"><span class="comment"># 是否继承了父类的方法</span></span><br><span class="line">dog.eat()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(Dog.__name__)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;__main__.Person object at 0x00000183883FFFD0&gt;</span></span><br><span class="line"><span class="string">[&lt;class &#x27;__main__.Person&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;]</span></span><br><span class="line"><span class="string">3</span></span><br><span class="line"><span class="string">狗狗趴着睡觉</span></span><br><span class="line"><span class="string">Yellow</span></span><br><span class="line"><span class="string">动物需要吃东西</span></span><br><span class="line"><span class="string">Dog</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="类装饰器-1"><a href="#类装饰器-1" class="headerlink" title="类装饰器"></a>类装饰器</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">类装饰器：</span></span><br><span class="line"><span class="string">    在不修改函数源代码的前提下，增加新的功能</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">AAA</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, func</span>):</span><br><span class="line">        <span class="comment"># print(&quot;我是AAA.init()&quot;)</span></span><br><span class="line">        self.__func = func</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 报错：TypeError: &#x27;AAA&#x27; object is not callable</span></span><br><span class="line">    <span class="comment"># 要实现call方法</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self, *args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;在这里可以实现新增任意功能&quot;</span>)</span><br><span class="line">        self.addFunc()</span><br><span class="line">        self.__func()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">addFunc</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;用户权限验证&quot;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;日志系统处理&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@AAA</span></span><br><span class="line"><span class="comment"># TypeError: __init__() takes 1 positional argument but 2 were given</span></span><br><span class="line"><span class="comment"># @AAA等价于test1 = AAA(test1)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test1</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;我是功能1&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">test1()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">在这里可以实现新增任意功能</span></span><br><span class="line"><span class="string">用户权限验证</span></span><br><span class="line"><span class="string">日志系统处理</span></span><br><span class="line"><span class="string">我是功能1</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h3 id="对象池"><a href="#对象池" class="headerlink" title="对象池"></a>对象池</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">对象池</span></span><br><span class="line"><span class="string">    1.数值类型</span></span><br><span class="line"><span class="string">        小整数池</span></span><br><span class="line"><span class="string">            小整数：  [-5,256]</span></span><br><span class="line"><span class="string">                程序开始时，一次性加载到内存</span></span><br><span class="line"><span class="string">                LEGB（局部变量，闭包中的变量，全局变量，内建变量）</span></span><br><span class="line"><span class="string">                全局都是同一个</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">                id()：</span></span><br><span class="line"><span class="string">                is:</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        大整数池</span></span><br><span class="line"><span class="string">            每创建一个不是小整数范围内的变量，都会被自动存储到大整数池中</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    2.字符串</span></span><br><span class="line"><span class="string">        intern机制</span></span><br><span class="line"><span class="string">        每个单词(字符串)，不夹杂空格或者其他符号，默认开启intern机制，共享内存，靠引用计数决定是否销毁</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h4 id="小整数池"><a href="#小整数池" class="headerlink" title="小整数池"></a>小整数池</h4><ul>
<li>系统默认创建好的，等着你使用。</li>
<li>概述：<br>整数在程序中的使用非常广泛，Python为了优化速度，使用了小整数对象池， 避免为整数频繁申请和销毁内存空间。Python 对小整数的定义是 <code>[-5, 256]</code> 这些整数对象是提前建立好的，不会被垃圾回收。在一个 Python 的程序中，无论这个整数处于LEGB（局部变量，闭包，全局，内建模块）中的哪个位置，所有位于这个范围内的整数使用的都是同一个对象。</li>
</ul>
<h4 id="大整数池"><a href="#大整数池" class="headerlink" title="大整数池"></a>大整数池</h4><p>默认创建出来，池内为空的，创建一个就会往池中存储一个</p>
<h4 id="intern机制"><a href="#intern机制" class="headerlink" title="intern机制"></a>intern机制</h4><p>每个单词(字符串)，不夹杂空格或者其他符号，默认开启intern机制，共享内存，靠引用计数决定是否销毁</p>
<h3 id="垃圾收集"><a href="#垃圾收集" class="headerlink" title="垃圾收集"></a>垃圾收集</h3><h4 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h4><p>现在的高级语言如Java，C#等，都采用了垃圾收集机制，而不再是C，C++里用户自己管理维护内存的方式。自己管理内存极其自由，可以任意申请内存，但如同一把双刃剑，为大量内存泄露，悬空指针等bug埋下隐患。Python里也同Java一样采用了垃圾收集机制，不过不一样的是：Python采用的是引用计数机制为主，标记-清除和分代收集两种机制为辅的策略。</p>
<h4 id="引用计数机制"><a href="#引用计数机制" class="headerlink" title="引用计数机制"></a>引用计数机制</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">垃圾回收机制：GC机制</span></span><br><span class="line"><span class="string">    Python：</span></span><br><span class="line"><span class="string">    1.引用计数机制为主</span></span><br><span class="line"><span class="string">        如何获取一个对象的引用计数？</span></span><br><span class="line"><span class="string">            sys.getrefcount(a)</span></span><br><span class="line"><span class="string">            刚创建对象引用计数为2</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        a.增加引用计数操作</span></span><br><span class="line"><span class="string">            1、如果有新的对象对象使用该对象，+1</span></span><br><span class="line"><span class="string">            2、装进列表 +1</span></span><br><span class="line"><span class="string">            3、作为函数参数</span></span><br><span class="line"><span class="string">        b.减少引用计数操作</span></span><br><span class="line"><span class="string">            1.如果有新的对象对象使用该对象，新对象不在使用-1</span></span><br><span class="line"><span class="string">            2.从列表中移除-1</span></span><br><span class="line"><span class="string">            3.函数调用结束</span></span><br><span class="line"><span class="string">            4.del 显示销毁</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    2.隔代回收为辅助</span></span><br><span class="line"><span class="string">        循环引用</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">AA</span>():</span><br><span class="line">    <span class="comment"># 创建对象开辟内存时调用</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls, *args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;开辟内存空间&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(AA, cls).__new__(cls)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 初始化方法</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;创建对象at:%s&quot;</span> % <span class="built_in">hex</span>(<span class="built_in">id</span>(self)))</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 对象被系统回之前，会调用该方法</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__del__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;%s say bye bye&quot;</span> % <span class="built_in">hex</span>(<span class="built_in">id</span>(self)))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test1</span>(<span class="params">aaa</span>):</span><br><span class="line">    <span class="built_in">print</span>(aaa)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a = AA()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line">b = a</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line">list1 = [a]</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line">test1(a)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">50</span>)</span><br><span class="line"></span><br><span class="line">b = <span class="number">100</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line">list1.remove(a)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a的引用计数为:%d&#x27;</span> % sys.getrefcount(a))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 1</span></span><br><span class="line"><span class="keyword">del</span> a</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;----------------程序结束-----------------&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">开辟内存空间</span></span><br><span class="line"><span class="string">创建对象at:0x1dd4d9dfeb0</span></span><br><span class="line"><span class="string">a的引用计数为:2</span></span><br><span class="line"><span class="string">a的引用计数为:3</span></span><br><span class="line"><span class="string">a的引用计数为:4</span></span><br><span class="line"><span class="string">&lt;__main__.AA object at 0x000001DD4D9DFEB0&gt;</span></span><br><span class="line"><span class="string">a的引用计数为:6</span></span><br><span class="line"><span class="string">a的引用计数为:4</span></span><br><span class="line"><span class="string">**************************************************</span></span><br><span class="line"><span class="string">a的引用计数为:3</span></span><br><span class="line"><span class="string">a的引用计数为:2</span></span><br><span class="line"><span class="string">0x1dd4d9dfeb0 say bye bye</span></span><br><span class="line"><span class="string">----------------程序结束-----------------</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<p>引用计数机制的优点：</p>
<ul>
<li>简单</li>
<li>实时性：一旦没有引用，内存就直接释放了。不用像其他机制等到特定时机。<br>实时性还带来一个好处：处理回收内存的时间分摊到了平时。</li>
</ul>
<p>引用计数机制的缺点：</p>
<ul>
<li>维护引用计数消耗资源</li>
<li>循环引用的问题无法解决（DOS窗口，查看内存tasklist，或者内存表，任务管理器）</li>
</ul>
<h4 id="隔代回收机制"><a href="#隔代回收机制" class="headerlink" title="隔代回收机制"></a>隔代回收机制</h4><p>分代回收是用来解决交叉引用(循环引用)，并增加数据回收的效率。 </p>
<p>原理：通过对象存在的时间不同，采用不同的算法来回收垃圾。 形象的比喻，三个链表，零代链表上的对象（新创建的对象都加入到零代链表），引用数都是一，每增加一个指针，引用加一，随后Python会检测列表中的互相引用的对象，根据规则减掉其引用计数。GC算法对链表一的引用减一，引用为0的，清除，不为0的到链表二，链表二也执行GC算法，链表三一样。存在时间越长的数据，越是有用的数据。</p>
<h5 id="隔代回收触发时间？（GC阈值）"><a href="#隔代回收触发时间？（GC阈值）" class="headerlink" title="隔代回收触发时间？（GC阈值）"></a>隔代回收触发时间？（GC阈值）</h5><p>随着你的程序运行，Python解释器保持对新创建的对象，以及因为引用计数为零而被释放掉的对象的追踪。从理论上说，这两个值应该保持一致，因为程序新建的每个对象都应该最终被释放掉。当然，事实并非如此。因为循环引用的原因，从而被分配对象的计数值与被释放对象的计数值之间的差异在逐渐增长。一旦这个差异累计超过某个阈值，则Python的收集机制就启动了，并且触发上边所说到的零代算法，释放“浮动的垃圾”，并且将剩下的对象移动到一代列表。随着时间的推移，程序所使用的对象逐渐从零代列表移动到一代列表。而Python对于一代列表中对象的处理遵循同样的方法，一旦被分配计数值与被释放计数值累计到达一定阈值，Python会将剩下的活跃对象移动到二代列表。通过这种方法，你的代码所长期使用的对象，那些你的代码持续访问的活跃对象，会从零代链表转移到一代再转移到二代。</p>
<p>通过不同的阈值设置，Python可以在不同的时间间隔处理这些对象。</p>
<p>Python处理零代最为频繁，其次是一代然后才是二代。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">垃圾回收机制：</span></span><br><span class="line"><span class="string">    1.引用计数机制</span></span><br><span class="line"><span class="string">        相互引用，引用计数无法删除类似的对象</span></span><br><span class="line"><span class="string">    2.隔代回收机制</span></span><br><span class="line"><span class="string">        原理：</span></span><br><span class="line"><span class="string">            随着时间的推进，程序冗余对象逐渐增多，达到一定数量（阈值），系统进行回收</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">            (0代，1代，2代)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        代码：</span></span><br><span class="line"><span class="string">        import gc</span></span><br><span class="line"><span class="string">        gc.get_count()</span></span><br><span class="line"><span class="string">        gc.get_threshold()   -&gt;(700,10,10)</span></span><br><span class="line"><span class="string">        gc.disable()</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> gc</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">AA</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__new__</span>(<span class="params">cls, *args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;new&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>(AA, cls).__new__(cls)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;object:born at %s&quot;</span> % <span class="built_in">hex</span>(<span class="built_in">id</span>(self)))</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__del__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;%s 被系统回收&quot;</span> % <span class="built_in">hex</span>(<span class="built_in">id</span>(self)))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">start</span>():</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        a = AA()</span><br><span class="line">        b = AA()</span><br><span class="line">        a.v = b</span><br><span class="line">        b.v = a</span><br><span class="line">        <span class="keyword">del</span> a</span><br><span class="line">        <span class="keyword">del</span> b</span><br><span class="line">        <span class="built_in">print</span>(gc.get_threshold())</span><br><span class="line">        <span class="built_in">print</span>(gc.get_count())</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 手动关闭垃圾回收机制</span></span><br><span class="line"><span class="comment"># gc.disable()</span></span><br><span class="line">gc.set_threshold(<span class="number">200</span>, <span class="number">10</span>, <span class="number">10</span>)</span><br><span class="line">start()</span><br><span class="line"></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafeb0</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafe80</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(2, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafdc0</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafd90</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(4, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafd00</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafcd0</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(6, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafc40</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafc10</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(8, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafb80</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafb50</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(10, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafac0</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafa90</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(12, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acafa00</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf9d0</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(14, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf940</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf910</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(16, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf880</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf850</span></span><br><span class="line"><span class="string">(20, 10, 10)</span></span><br><span class="line"><span class="string">(18, 4, 1)</span></span><br><span class="line"><span class="string">new</span></span><br><span class="line"><span class="string">object:born at 0x2442acaf7c00x2442acafeb0 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafe80 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafdc0 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafd90 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafd00 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafcd0 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafc40 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafc10 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafb80 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafb50 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafac0 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafa90 被系统回收</span></span><br><span class="line"><span class="string">0x2442acafa00 被系统回收</span></span><br><span class="line"><span class="string">0x2442acaf9d0 被系统回收</span></span><br><span class="line"><span class="string">0x2442acaf940 被系统回收</span></span><br><span class="line"><span class="string">0x2442acaf910 被系统回收</span></span><br><span class="line"><span class="string">0x2442acaf880 被系统回收</span></span><br><span class="line"><span class="string">0x2442acaf850 被系统回收</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
<h5 id="查看引用计数"><a href="#查看引用计数" class="headerlink" title="查看引用计数"></a>查看引用计数</h5><h6 id="gc模块的使用"><a href="#gc模块的使用" class="headerlink" title="gc模块的使用"></a>gc模块的使用</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 常用函数：</span></span><br><span class="line"><span class="comment"># 1、获取当前自动执行垃圾回收的计数器，返回一个长度为3的列表</span></span><br><span class="line">gc.get_count()</span><br><span class="line"><span class="comment"># 2、获取gc模块中自动执行垃圾回收的频率</span></span><br><span class="line">gc.get_threshold()</span><br><span class="line"><span class="comment"># 3、设置自动执行垃圾回收的频率</span></span><br><span class="line">gc.set_threshold(threshold0[,threshold1,threshold2])</span><br><span class="line"><span class="comment"># 4、python3默认开启gc机制，可以使用该方法手动关闭gc机制</span></span><br><span class="line">gc.disable()</span><br><span class="line"><span class="comment"># 5、手动调用垃圾回收机制回收垃圾</span></span><br><span class="line">gc.collect()</span><br></pre></td></tr></table></figure>
<h6 id="增加引用计数的条件"><a href="#增加引用计数的条件" class="headerlink" title="增加引用计数的条件"></a>增加引用计数的条件</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1.创建对象</span></span><br><span class="line">stu = Student()</span><br><span class="line"><span class="comment"># 2.将对象加入列表</span></span><br><span class="line">list1.append(stu)</span><br><span class="line"><span class="comment"># 3.对象被引用</span></span><br><span class="line">stu2 = stu</span><br><span class="line"><span class="comment"># 4.将对象作为参数，传入某个函数</span></span><br><span class="line">func(stu)</span><br></pre></td></tr></table></figure>
<h6 id="减少对象引用计数的情况"><a href="#减少对象引用计数的情况" class="headerlink" title="减少对象引用计数的情况"></a>减少对象引用计数的情况</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1.对象被显示销毁</span></span><br><span class="line"><span class="keyword">del</span> stu</span><br><span class="line"><span class="comment"># 2.对象名指向新的对象</span></span><br><span class="line">stu = Student()</span><br><span class="line"><span class="comment"># 3.从容器中移除，或者显示销毁列表</span></span><br><span class="line">list1.remove(stu)</span><br><span class="line">list1.pop(stu)</span><br><span class="line"><span class="comment"># 4.局部变量对象，作为函数参数</span></span><br><span class="line"><span class="comment"># 函数结束时，引用计数-1</span></span><br></pre></td></tr></table></figure>
<h6 id="获取某个对象的引用计数"><a href="#获取某个对象的引用计数" class="headerlink" title="获取某个对象的引用计数"></a>获取某个对象的引用计数</h6><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> sys</span><br><span class="line">obj = <span class="string">&#x27;Helloworld&#x27;</span></span><br><span class="line">sys.getrefcount(obj)</span><br><span class="line">list1 = []</span><br><span class="line"><span class="built_in">list</span>.append(obj)</span><br><span class="line">sys.getrefcount(obj)</span><br></pre></td></tr></table></figure>
<h3 id="内建函数"><a href="#内建函数" class="headerlink" title="内建函数"></a>内建函数</h3><p>什么叫内建函数：启动python解释器后，默认加载的函数称为内建函数</p>
<h4 id="如何查看内建函数"><a href="#如何查看内建函数" class="headerlink" title="如何查看内建函数"></a>如何查看内建函数</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 两种方式：</span></span><br><span class="line">a. </span><br><span class="line"><span class="built_in">dir</span>(__builtins__)</span><br><span class="line">b. </span><br><span class="line"><span class="keyword">import</span> builtins</span><br><span class="line"><span class="built_in">dir</span>(builtins)</span><br></pre></td></tr></table></figure>
<h4 id="常用内建函数"><a href="#常用内建函数" class="headerlink" title="常用内建函数"></a>常用内建函数</h4><h5 id="range"><a href="#range" class="headerlink" title="range()"></a>range()</h5><p>Python <code>range()</code> 函数可创建一个整数列表，一般用在 for 循环中。<br>        语法：<code>range(start, stop[, step])</code></p>
<p>参数说明：</p>
<p>start: 计数从 start 开始。默认是从 0 开始。例如<code>range(5)</code>等价于<code>range(0, 5)</code>;</p>
<p>stop: 计数到 stop 结束，但不包括 stop。例如：<code>range(0, 5)</code> 是<code>[0, 1, 2, 3, 4]</code>没有5</p>
<p>step：步长，默认为1。例如：<code>range(0, 5)</code> 等价于 <code>range(0, 5, 1)</code></p>
<p>返回：range</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">range(stop)</span></span><br><span class="line"><span class="string">    默认从0开始，直到stop-1</span></span><br><span class="line"><span class="string">    list1 = list(range(10))</span></span><br><span class="line"><span class="string">print(list1)</span></span><br><span class="line"><span class="string">range(start[,stop,step])</span></span><br><span class="line"><span class="string">    start:表示开始</span></span><br><span class="line"><span class="string">    stop：表示结束(不包括该元素)</span></span><br><span class="line"><span class="string">        负值</span></span><br><span class="line"><span class="string">    step:表示迭代的步长</span></span><br><span class="line"><span class="string">        默认为1</span></span><br><span class="line"><span class="string">        负值，表示递减</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="comment"># 创建列表的时候</span></span><br><span class="line">list1 = <span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">10</span>))</span><br><span class="line">list1 = <span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">0</span>, <span class="number">10</span>, <span class="number">1</span>))</span><br><span class="line">list1 = <span class="built_in">list</span>(<span class="built_in">range</span>(<span class="number">0</span>, <span class="number">10</span>, <span class="number">2</span>))</span><br><span class="line"><span class="built_in">print</span>(list1)</span><br><span class="line"><span class="comment"># 打印[1-10]之间的数据</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&quot; &quot;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>, <span class="number">2</span>):</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&quot; &quot;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>, -<span class="number">1</span>, -<span class="number">1</span>):</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&quot; &quot;</span>)</span><br><span class="line">    <span class="built_in">print</span>()</span><br><span class="line">    </span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>, -<span class="number">1</span>, -<span class="number">2</span>):</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&quot; &quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Iterable</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">isinstance</span>(<span class="built_in">range</span>(<span class="number">10</span>), Iterable))</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br></pre></td></tr></table></figure>
<h5 id="map"><a href="#map" class="headerlink" title="map()"></a>map()</h5><p><code>map()</code> 会根据提供的函数对指定序列做映射。</p>
<p>第一个参数 function 以参数序列中的每一个元素调用 function 函数，</p>
<p>返回包含每次 function 函数返回值的新列表。</p>
<p>语法：</p>
<p><code>map(function, iterable, ...)</code></p>
<p>参数说明：</p>
<p>function：函数</p>
<p>iterable：一个或多个序列</p>
<p>返回：</p>
<p>Python 2.x 返回列表。</p>
<p>Python 3.x 返回迭代器。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">map()</span></span><br><span class="line"><span class="string">map(func, *iterables) --&gt; map object</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    Make an iterator that computes the function using arguments from</span></span><br><span class="line"><span class="string">    each of the iterables.  Stops when the shortest iterable is exhausted.</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Iterable, Iterator</span><br><span class="line"></span><br><span class="line">list1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">list2 = [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func1</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="number">2</span> * x</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func2</span>(<span class="params">x, y</span>):</span><br><span class="line">    <span class="keyword">return</span> x + y</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成一个迭代器</span></span><br><span class="line"><span class="comment"># it1 = map(func1,list1)</span></span><br><span class="line">it1 = <span class="built_in">map</span>(<span class="keyword">lambda</span> x: <span class="number">2</span> * x, list1)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">isinstance</span>(it1, Iterator))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> it1:</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;-------------------&#x27;</span>)</span><br><span class="line"><span class="comment"># it2 = map(func2,list1,list2)</span></span><br><span class="line">it2 = <span class="built_in">map</span>(<span class="keyword">lambda</span> x, y: x + y, list1, list2)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> it2:</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;--------------------&#x27;</span>)</span><br></pre></td></tr></table></figure>
<h5 id="filter"><a href="#filter" class="headerlink" title="filter()"></a>filter()</h5><p>filter() 函数用于过滤序列，过滤掉不符合条件的元素，返回由符合条件元素组成的新列表。</p>
<p>该接收两个参数，第一个为函数，第二个为序列，序列的每个元素作为参数传递给函数进行判断，然后返回 True 或 False，最后将返回 True 的元素放到新列表中。</p>
<p>语法：</p>
<p><code>filter(function, iterable)</code></p>
<p>参数说明：</p>
<p>function：判断函数。</p>
<p>iterable：可迭代对象。</p>
<p>返回：</p>
<p>返回迭代器。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">filter()</span></span><br><span class="line"><span class="string">filter(function or None, iterable) --&gt; filter object</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    Return an iterator yielding those items of iterable for which function(item)</span></span><br><span class="line"><span class="string">    is true. If function is None, return the items that are true</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line">list1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">10</span>, <span class="number">0</span>, <span class="number">25</span>]</span><br><span class="line"><span class="comment"># 遍历列表中不为0的元素</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> list1:</span><br><span class="line">    <span class="keyword">if</span> i != <span class="number">0</span>:</span><br><span class="line">        <span class="built_in">print</span>(i, end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"><span class="comment"># it1 = filter(None,list1)</span></span><br><span class="line"><span class="comment"># for i in it1:</span></span><br><span class="line"><span class="comment">#     print(i,end=&#x27; &#x27;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># it1 = filter(lambda x:x != 0,list1)</span></span><br><span class="line"><span class="comment"># for i in it1:</span></span><br><span class="line"><span class="comment">#     print(i,end=&#x27; &#x27;)</span></span><br><span class="line">it1 = <span class="built_in">filter</span>(<span class="keyword">lambda</span> x: x &gt;= <span class="number">5</span>, list1)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> it1:</span><br><span class="line">    <span class="built_in">print</span>(i, end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="reduce"><a href="#reduce" class="headerlink" title="reduce()"></a>reduce()</h5><p>3.x后，需要先<code>from functools import reduce</code></p>
<p><code>reduce()</code> 函数会对参数序列中元素进行累积。函数将一个数据集合（链表，元组等）中的所有数据进行下列操作：</p>
<p>用传给reduce中的函数 function（有两个参数）先对集合中的第 1、2 个元素进行操作，得到的结果再与第三个数据用 function 函数运算，最后得到一个结果。</p>
<p>语法：</p>
<p><code>reduce(function, iterable[, initializer])</code></p>
<p>参数说明：</p>
<p>function：函数，有两个参数</p>
<p>iterable：可迭代对象</p>
<p>initializer：可选，初始参数</p>
<p>返回：</p>
<p>返回函数计算结果</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">reduce()</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">需要先从functools 引入</span></span><br><span class="line"><span class="string">需求：</span></span><br><span class="line"><span class="string">    有一个存储了5个随机整数的列表，求列表中所有元素的和</span></span><br><span class="line"><span class="string">    1.生成随机列表</span></span><br><span class="line"><span class="string">    2.遍历求和/或者用其他方式求和  reduce()</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> reduce</span><br><span class="line"></span><br><span class="line">list1 = []</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>):</span><br><span class="line">    rand_num = random.randint(<span class="number">1</span>, <span class="number">100</span>)</span><br><span class="line">    list1.append(rand_num)</span><br><span class="line"><span class="built_in">print</span>(list1)</span><br><span class="line"></span><br><span class="line">sum1 = <span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> list1:</span><br><span class="line">    sum1 += i</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;和为:%g&#x27;</span> % sum1)</span><br><span class="line"></span><br><span class="line">result = reduce(<span class="keyword">lambda</span> x, y: x + y, list1)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;和为:%g&#x27;</span> % result)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="sorted"><a href="#sorted" class="headerlink" title="sorted()"></a>sorted()</h5><p>sorted() 函数对所有可迭代的对象进行排序操作。</p>
<p>sort 与 sorted 区别：</p>
<p>sort 是应用在 list 上的方法，sorted 可以对所有可迭代的对象进行排序操作。</p>
<p>list 的 sort 方法返回的是对已经存在的列表进行操作，而内建函数 sorted 方法返回的是一个新的 list，而不是在原来的基础上进行的操作。</p>
<p>语法：</p>
<p><code>sorted(iterable[, key[, reverse]])</code></p>
<p>参数说明：</p>
<p>iterable：可迭代对象。</p>
<p>key：主要是用来进行比较的元素，只有一个参数，具体的函数的参数就是取自于可迭代对象中，指定可迭代对象中的一个元素来进行排序。</p>
<p>reverse：排序规则，reverse = True 降序 ， reverse = False 升序（默认）</p>
<p>返回：</p>
<p>返回重新排序的列表。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">list.sort()</span></span><br><span class="line"><span class="string">无返回值，对源数据进行排序</span></span><br><span class="line"><span class="string">sorted()</span></span><br><span class="line"><span class="string">有返回值，返回排序备份</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">sort(iterable,key=None,reverse=False)</span></span><br><span class="line"><span class="string">Return a new list containing all items from the iterable in ascending order.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    A custom key function can be supplied to customize the sort order, and the</span></span><br><span class="line"><span class="string">    reverse flag can be set to request the result in descending order.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line">list1 = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">9</span>, <span class="number">29</span>, <span class="number">3</span>]</span><br><span class="line">list2 = <span class="built_in">sorted</span>(list1)</span><br><span class="line">list3 = <span class="built_in">sorted</span>(list1, reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(list2)</span><br><span class="line"><span class="built_in">print</span>(list3)</span><br><span class="line"><span class="comment"># 正数从小到大，负数从大到小</span></span><br><span class="line">list1 = [<span class="number">1</span>, <span class="number">0</span>, -<span class="number">9</span>, <span class="number">29</span>, <span class="number">3</span>, -<span class="number">10</span>, -<span class="number">2</span>, -<span class="number">5</span>]</span><br><span class="line">list2 = <span class="built_in">sorted</span>(list1, key=<span class="keyword">lambda</span> x: (x &lt; <span class="number">0</span>, <span class="built_in">abs</span>(x)))</span><br><span class="line"><span class="built_in">print</span>(list2)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 列表中自定义对象的排序</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>():</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">stu1 = Student(<span class="string">&#x27;aaa&#x27;</span>, <span class="number">19</span>)</span><br><span class="line">stu2 = Student(<span class="string">&#x27;ccc&#x27;</span>, <span class="number">20</span>)</span><br><span class="line">stu3 = Student(<span class="string">&#x27;bbb&#x27;</span>, <span class="number">18</span>)</span><br><span class="line"></span><br><span class="line">list1 = [stu1, stu2, stu3]</span><br><span class="line"><span class="keyword">for</span> stu <span class="keyword">in</span> list1:</span><br><span class="line">    <span class="built_in">print</span>(stu.name, stu.age)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;---------------------&quot;</span>)</span><br><span class="line"><span class="comment"># list2 = sorted(list1,key=lambda x:x.age)</span></span><br><span class="line">list2 = <span class="built_in">sorted</span>(list1, key=<span class="keyword">lambda</span> x: x.name)</span><br><span class="line"><span class="keyword">for</span> stu <span class="keyword">in</span> list2:</span><br><span class="line">    <span class="built_in">print</span>(stu.name, stu.age)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="偏函数-1"><a href="#偏函数-1" class="headerlink" title="偏函数"></a>偏函数</h3><p>概念：python 中提供一种用于对函数固定属性的函数</p>
<p>定义:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line">int3 = partial(<span class="built_in">int</span>,base=<span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(int3(<span class="string">&#x27;1010&#x27;</span>))</span><br></pre></td></tr></table></figure>
<p>作用：把一个函数的某些参数给固定住（也就是设置默认值），返回一个新的函数，调用这个新函数会更简单。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">偏函数的使用：</span></span><br><span class="line"><span class="string">partial</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> partial</span><br><span class="line"></span><br><span class="line">str1 = <span class="string">&#x27;1010&#x27;</span></span><br><span class="line">result = <span class="built_in">int</span>(str1, <span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 重新定义一个函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">int2</span>(<span class="params">n, base=<span class="number">2</span></span>):</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">int</span>(n, base)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># result = int(str1,2)</span></span><br><span class="line">result = int2(str1)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用偏函数完成类似的功能</span></span><br><span class="line">int3 = partial(<span class="built_in">int</span>, base=<span class="number">2</span>)</span><br><span class="line"><span class="comment"># print(type(int3))</span></span><br><span class="line"><span class="built_in">print</span>(int3(str1))</span><br></pre></td></tr></table></figure>
<h3 id="wraps"><a href="#wraps" class="headerlink" title="wraps"></a>wraps</h3><p>作用：<code>functools.wraps</code> 可以将原函数对象的指定属性复制给包装函数对象, 默认有 <code>__module__</code>、<code>__name__</code>、<code>__doc__</code>,或者通过参数选择。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">wraps函数的使用</span></span><br><span class="line"><span class="string">from functools import wraps</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">作用：</span></span><br><span class="line"><span class="string">functools.wraps 可以将原函数对象的指定属性</span></span><br><span class="line"><span class="string">复制给包装函数对象, 默认有 module、name、doc,或者通过参数选择</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> wraps</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">log</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">with_logging</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;%s was calling&quot;</span> % func.__name__)</span><br><span class="line">        <span class="keyword">return</span> func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> with_logging</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@log</span></span><br><span class="line"><span class="comment"># test = log(test)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;求x*x的值&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> x * x</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(test.__name__)</span><br><span class="line"><span class="built_in">print</span>(test.__doc__)</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">with_logging</span></span><br><span class="line"><span class="string">None</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://huaiyuechusan.github.io">SanShui</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://huaiyuechusan.github.io/archives/fab44cdf.html">https://huaiyuechusan.github.io/archives/fab44cdf.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="external nofollow noreferrer" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://huaiyuechusan.github.io" target="_blank">SanShui的个人博客</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E5%AD%A6%E4%B9%A0%E6%8A%80%E6%9C%AF/">学习技术</a><a class="post-meta__tags" href="/tags/Python/">Python</a></div><div class="post_share"><div class="social-share" data-image="http://wallpaper.csun.site/?7" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src="/img/wechat.jpg" alt="wechat"/></a><div class="post-qr-code-desc">wechat</div></li><li class="reward-item"><a href="/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="/img/alipay.jpg" alt="alipay"/></a><div class="post-qr-code-desc">alipay</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/archives/984515cf.html"><img class="prev-cover" src="http://wallpaper.csun.site/?6" onerror="onerror=null;src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Python 网络与并发编程</div></div></a></div><div class="next-post pull-right"><a href="/archives/283f9737.html"><img class="next-cover" src="http://wallpaper.csun.site/?15" onerror="onerror=null;src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">竞赛总结：智能驾驶汽车虚拟仿真视频数据理解</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/archives/984515cf.html" title="Python 网络与并发编程"><img class="cover" src="http://wallpaper.csun.site/?6" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">Python 网络与并发编程</div></div></a></div><div><a href="/archives/8df5f8b9.html" title="Python深入和提高"><img class="cover" src="http://wallpaper.csun.site/?5" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">Python深入和提高</div></div></a></div><div><a href="/archives/d9ef328.html" title="Python入门"><img class="cover" src="http://wallpaper.csun.site/?4" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">Python入门</div></div></a></div><div><a href="/archives/6d169344.html" title="云函数调用request请求"><img class="cover" src="http://wallpaper.csun.site/?21" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">云函数调用request请求</div></div></a></div><div><a href="/archives/d4b1abad.html" title="下载M3U8格式加密视频"><img class="cover" src="http://wallpaper.csun.site/?22" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">下载M3U8格式加密视频</div></div></a></div><div><a href="/archives/59cb3162.html" title="大数据集群软件启动脚本"><img class="cover" src="http://wallpaper.csun.site/?11" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2024-10-17</div><div class="title">大数据集群软件启动脚本</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="lv-container" data-id="city" data-uid="MTAyMC81OTEzMS8zNTU5Mw=="></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/./img/config_img/%E9%98%B3%E5%85%89%E5%B0%8F%E7%8C%AB.jpg" onerror="this.onerror=null;this.src='/./img/config_img/%E8%93%9D%E5%A4%A9.jpg'" alt="avatar"/></div><div class="author-info__name">SanShui</div><div class="author-info__description">今天不学习，明天变垃圾</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">25</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">16</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">11</div></a></div><a id="card-info-btn" target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/huaiyuechusan"><i class="fa-sharp fa-solid fa-plane"></i><span>欢迎关注我的Github</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/huaiyuechusan" rel="external nofollow noreferrer" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="https://huaiyuechusan.github.io/atom.xml" target="_blank" title=""><i class="fas fa-rss"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到SanShui的博客</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B%E5%92%8CPython%E6%96%B0%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7"><span class="toc-text">函数式编程和Python新核心特性</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B%E6%A0%B8%E5%BF%83-%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0%E3%80%81%E9%97%AD%E5%8C%85%E7%AD%89"><span class="toc-text">函数式编程核心(高阶函数、闭包等)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0%E5%92%8C%E5%86%85%E5%AD%98%E5%88%86%E6%9E%90"><span class="toc-text">高阶函数和内存分析</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E6%98%AF%E4%B8%80%E7%AD%89%E5%85%AC%E6%B0%91"><span class="toc-text">函数是一等公民</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0-%E5%86%85%E5%AD%98%E7%8A%B6%E6%80%81%E5%88%86%E6%9E%90"><span class="toc-text">高阶函数_内存状态分析</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%92%8C%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0"><span class="toc-text">lambda表达式和匿名函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%81%8F%E5%87%BD%E6%95%B0"><span class="toc-text">偏函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%97%AD%E5%8C%85closure"><span class="toc-text">闭包closure</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%97%AD%E5%8C%85%E6%A6%82%E5%BF%B5%E5%92%8C%E7%AC%AC%E4%B8%80%E4%B8%AA%E9%97%AD%E5%8C%85%E7%A8%8B%E5%BA%8F"><span class="toc-text">闭包概念和第一个闭包程序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%97%AD%E5%8C%85%E5%86%85%E5%AD%98%E5%88%86%E6%9E%90"><span class="toc-text">闭包内存分析</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%97%AD%E5%8C%85%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-text">闭包的作用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%97%AD%E5%8C%85%E5%92%8C%E8%87%AA%E7%94%B1%E5%8F%98%E9%87%8F"><span class="toc-text">闭包和自由变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B%EF%BC%9A%E7%94%A8%E9%97%AD%E5%8C%85%E5%AE%9E%E7%8E%B0%E4%B8%8D%E4%BF%AE%E6%94%B9%E6%BA%90%E7%A0%81%E6%B7%BB%E5%8A%A0%E5%8A%9F%E8%83%BD"><span class="toc-text">案例：用闭包实现不修改源码添加功能</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#map%E5%87%BD%E6%95%B0%EF%BC%88%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0%EF%BC%89"><span class="toc-text">map函数（内置函数）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#reduce%E5%87%BD%E6%95%B0%EF%BC%88%E4%BD%8D%E4%BA%8Efunctools%E6%A8%A1%E5%9D%97%EF%BC%89"><span class="toc-text">reduce函数（位于functools模块）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#filter%E5%87%BD%E6%95%B0%EF%BC%88%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0%EF%BC%89"><span class="toc-text">filter函数（内置函数）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#sorted%E5%87%BD%E6%95%B0%EF%BC%88%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0%EF%BC%89"><span class="toc-text">sorted函数（内置函数）</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A3%85%E9%A5%B0%E5%99%A8%E6%B7%B1%E5%85%A5%E5%89%96%E6%9E%90"><span class="toc-text">装饰器深入剖析</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A6%82%E5%BF%B5"><span class="toc-text">概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A3%85%E9%A5%B0%E5%99%A8%E8%A7%A3%E5%86%B3%E6%97%A5%E5%BF%97%E9%97%AE%E9%A2%98"><span class="toc-text">装饰器解决日志问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%9A%E4%B8%AA%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-text">多个装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-text">带参数的装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#wraps%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-text">wraps装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%86%85%E7%BD%AE%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-text">内置装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E8%A3%85%E9%A5%B0%E5%99%A8"><span class="toc-text">类装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E8%A3%85%E9%A5%B0%E5%99%A8%E5%92%8C%E8%AE%A1%E6%97%B6%E8%A3%85%E9%A5%B0%E5%99%A8%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0"><span class="toc-text">缓存装饰器和计时装饰器综合练习</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%9F%E6%88%90%E5%99%A8%E3%80%81%E8%BF%AD%E4%BB%A3%E5%99%A8%E3%80%81%E5%8A%A8%E6%80%81%E6%80%A7"><span class="toc-text">生成器、迭代器、动态性</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%94%9F%E6%88%90%E5%99%A8"><span class="toc-text">生成器</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%9F%E6%88%90%E5%99%A8%E5%AE%9A%E4%B9%89"><span class="toc-text">生成器定义</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E6%9C%89%E7%94%9F%E6%88%90%E5%99%A8"><span class="toc-text">为什么要有生成器</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E7%94%9F%E6%88%90%E5%99%A8%E7%9A%84%E6%96%B9%E5%BC%8F%E4%B8%80%EF%BC%88%E7%94%9F%E6%88%90%E5%99%A8%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%89"><span class="toc-text">创建生成器的方式一（生成器表达式）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E7%94%9F%E6%88%90%E5%99%A8%E7%9A%84%E6%96%B9%E5%BC%8F%E4%BA%8C%EF%BC%88%E7%94%9F%E6%88%90%E5%99%A8%E5%87%BD%E6%95%B0%EF%BC%89"><span class="toc-text">创建生成器的方式二（生成器函数）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%9F%E6%88%90%E5%99%A8%E5%87%BD%E6%95%B0%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"><span class="toc-text">生成器函数的工作原理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-text">总结</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%BF%AD%E4%BB%A3%E5%99%A8"><span class="toc-text">迭代器</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A6%82%E5%BF%B5-1"><span class="toc-text">概念</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%AF%E8%BF%AD%E4%BB%A3%E5%AF%B9%E8%B1%A1%E5%92%8C%E8%BF%AD%E4%BB%A3%E5%99%A8%E5%8C%BA%E5%88%AB"><span class="toc-text">可迭代对象和迭代器区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#for%E5%BE%AA%E7%8E%AF%E7%9A%84%E6%9C%AC%E8%B4%A8"><span class="toc-text">for循环的本质</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E8%BF%AD%E4%BB%A3%E5%99%A8"><span class="toc-text">创建一个迭代器</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8A%A8%E6%80%81%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-text">动态添加属性和方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BB%99%E5%AF%B9%E8%B1%A1%E5%8A%A8%E6%80%81%E7%9A%84%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-text">给对象动态的添加属性和方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#type-MethonType%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">type.MethonType的使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BB%99%E7%B1%BB%E5%8A%A8%E6%80%81%E7%9A%84%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E3%80%81%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%E4%BB%A5%E5%8F%8A%E7%B1%BB%E6%96%B9%E6%B3%95"><span class="toc-text">给类动态的添加属性、静态方法以及类方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#slots-%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-text">__slots__ 的作用</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="toc-text">正则表达式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%A6%82%E5%BF%B5"><span class="toc-text">正则表达式概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#match%E5%87%BD%E6%95%B0%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">match函数的使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B8%B8%E7%94%A8%E5%8C%B9%E9%85%8D%E7%AC%A6"><span class="toc-text">常用匹配符</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%99%90%E5%AE%9A%E7%AC%A6"><span class="toc-text">限定符</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%99%90%E5%AE%9A%E7%AC%A6%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="toc-text">限定符使用实例</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E7%94%9F%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-text">原生字符串</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%BE%B9%E7%95%8C%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-text">边界字符串</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#search%E5%87%BD%E6%95%B0"><span class="toc-text">search函数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#match%E5%92%8Csearch%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">match和search的区别</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8B%A9%E4%B8%80%E5%8C%B9%E9%85%8D%EF%BC%88-%EF%BC%89%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">择一匹配（|）的使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%86%E7%BB%84"><span class="toc-text">分组</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#re%E6%A8%A1%E5%9D%97%E4%B8%AD%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E7%9A%84%E5%87%BD%E6%95%B0"><span class="toc-text">re模块中其他常用的函数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#sub%E5%92%8Csubn%E6%90%9C%E7%B4%A2%E4%B8%8E%E6%9B%BF%E6%8D%A2"><span class="toc-text">sub和subn搜索与替换</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#compile%E5%87%BD%E6%95%B0"><span class="toc-text">compile函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#findall%E5%87%BD%E6%95%B0"><span class="toc-text">findall函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#finditer%E5%87%BD%E6%95%B0"><span class="toc-text">finditer函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#split%E5%87%BD%E6%95%B0"><span class="toc-text">split函数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%B4%AA%E5%A9%AA%E6%A8%A1%E5%BC%8F%E5%92%8C%E9%9D%9E%E8%B4%AA%E5%A9%AA%E6%A8%A1%E5%BC%8F"><span class="toc-text">贪婪模式和非贪婪模式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Python%E6%96%B0%E7%89%B9%E6%80%A7"><span class="toc-text">Python新特性</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#formatted%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AD%97%E9%9D%A2%E5%80%BC"><span class="toc-text">formatted字符串字面值</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#formatted%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%94%AF%E6%8C%81"><span class="toc-text">formatted字符串支持 &#x3D;</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%96%B0%E6%96%B9%E6%B3%95"><span class="toc-text">字符串新方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B%E6%A0%87%E6%B3%A8"><span class="toc-text">变量类型标注</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E7%94%A8%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="toc-text">常用的数据类型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%AE%80%E5%8C%96%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B%E6%A0%87%E6%B3%A8"><span class="toc-text">简化变量类型标注</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E8%BF%94%E5%9B%9E%E5%80%BC%E6%B7%BB%E5%8A%A0%E7%B1%BB%E5%9E%8B%E6%A0%87%E6%B3%A8"><span class="toc-text">函数参数返回值添加类型标注</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B7%B7%E5%90%88%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%E6%94%B9%E8%BF%9B"><span class="toc-text">混合类型检查改进</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E6%9B%B4%E6%94%B9"><span class="toc-text">类型别名更改</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8C%E8%BF%9B%E5%88%B6%E8%A1%A8%E7%A4%BA%E9%A2%91%E7%8E%87%E4%B8%BA1%E7%9A%84%E6%95%B0%E9%87%8F%E7%BB%9F%E8%AE%A1"><span class="toc-text">二进制表示频率为1的数量统计</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E5%85%B8%E7%9A%84%E4%B8%89%E4%B8%AA%E6%96%B9%E6%B3%95%E6%96%B0%E5%A2%9Emapping%E5%B1%9E%E6%80%A7"><span class="toc-text">字典的三个方法新增mapping属性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%BD%E6%95%B0zip-%E6%96%B0%E5%A2%9Estrict%E5%8F%82%E6%95%B0"><span class="toc-text">函数zip()新增strict参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#dataclass"><span class="toc-text">dataclass</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E7%B1%BB"><span class="toc-text">使用类</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8dataclass"><span class="toc-text">使用dataclass</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#dataclass%E8%A3%85%E9%A5%B0%E5%99%A8%E4%B8%8A%E7%9A%84%E5%8F%82%E6%95%B0"><span class="toc-text">dataclass装饰器上的参数</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#dataclass%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E9%A2%9D%E5%A4%96%E8%AE%BE%E7%BD%AE"><span class="toc-text">dataclass成员变量额外设置</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#dataclass%E5%BB%BA%E7%AB%8B%E7%B1%BB%E5%8F%98%E9%87%8F"><span class="toc-text">dataclass建立类变量</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E5%85%B8%E5%90%88%E5%B9%B6"><span class="toc-text">字典合并</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#match%E8%AF%AD%E6%B3%95"><span class="toc-text">match语法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86"><span class="toc-text">内存管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%83%E7%B1%BB"><span class="toc-text">元类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E8%A3%85%E9%A5%B0%E5%99%A8-1"><span class="toc-text">类装饰器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E6%B1%A0"><span class="toc-text">对象池</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B0%8F%E6%95%B4%E6%95%B0%E6%B1%A0"><span class="toc-text">小整数池</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A4%A7%E6%95%B4%E6%95%B0%E6%B1%A0"><span class="toc-text">大整数池</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#intern%E6%9C%BA%E5%88%B6"><span class="toc-text">intern机制</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86"><span class="toc-text">垃圾收集</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A6%82%E8%BF%B0"><span class="toc-text">概述</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0%E6%9C%BA%E5%88%B6"><span class="toc-text">引用计数机制</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%9A%94%E4%BB%A3%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6"><span class="toc-text">隔代回收机制</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E9%9A%94%E4%BB%A3%E5%9B%9E%E6%94%B6%E8%A7%A6%E5%8F%91%E6%97%B6%E9%97%B4%EF%BC%9F%EF%BC%88GC%E9%98%88%E5%80%BC%EF%BC%89"><span class="toc-text">隔代回收触发时间？（GC阈值）</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%9F%A5%E7%9C%8B%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0"><span class="toc-text">查看引用计数</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#gc%E6%A8%A1%E5%9D%97%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-text">gc模块的使用</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#%E5%A2%9E%E5%8A%A0%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0%E7%9A%84%E6%9D%A1%E4%BB%B6"><span class="toc-text">增加引用计数的条件</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#%E5%87%8F%E5%B0%91%E5%AF%B9%E8%B1%A1%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0%E7%9A%84%E6%83%85%E5%86%B5"><span class="toc-text">减少对象引用计数的情况</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#%E8%8E%B7%E5%8F%96%E6%9F%90%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0"><span class="toc-text">获取某个对象的引用计数</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%86%85%E5%BB%BA%E5%87%BD%E6%95%B0"><span class="toc-text">内建函数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8B%E5%86%85%E5%BB%BA%E5%87%BD%E6%95%B0"><span class="toc-text">如何查看内建函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E7%94%A8%E5%86%85%E5%BB%BA%E5%87%BD%E6%95%B0"><span class="toc-text">常用内建函数</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#range"><span class="toc-text">range()</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#map"><span class="toc-text">map()</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#filter"><span class="toc-text">filter()</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#reduce"><span class="toc-text">reduce()</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#sorted"><span class="toc-text">sorted()</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%81%8F%E5%87%BD%E6%95%B0-1"><span class="toc-text">偏函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#wraps"><span class="toc-text">wraps</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/archives/6ca065c5.html" title="SanShui API 使用教程"><img src="http://wallpaper.csun.site/?abc" onerror="this.onerror=null;this.src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="SanShui API 使用教程"/></a><div class="content"><a class="title" href="/archives/6ca065c5.html" title="SanShui API 使用教程">SanShui API 使用教程</a><time datetime="2025-03-13T13:21:12.311Z" title="更新于 2025-03-13 21:21:12">2025-03-13</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/archives/b5700173.html" title="微信小程序定时订阅消息问题"><img src="http://wallpaper.csun.site/?25" onerror="this.onerror=null;this.src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="微信小程序定时订阅消息问题"/></a><div class="content"><a class="title" href="/archives/b5700173.html" title="微信小程序定时订阅消息问题">微信小程序定时订阅消息问题</a><time datetime="2024-10-17T12:04:53.379Z" title="更新于 2024-10-17 20:04:53">2024-10-17</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/archives/638889b7.html" title="深度学习回归任务训练代码模版"><img src="http://wallpaper.csun.site/?24" onerror="this.onerror=null;this.src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="深度学习回归任务训练代码模版"/></a><div class="content"><a class="title" href="/archives/638889b7.html" title="深度学习回归任务训练代码模版">深度学习回归任务训练代码模版</a><time datetime="2024-10-17T12:04:09.066Z" title="更新于 2024-10-17 20:04:09">2024-10-17</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/archives/7cb9f0a8.html" title="通过nginx访问tomcat中SpringMVC应用"><img src="http://wallpaper.csun.site/?23" onerror="this.onerror=null;this.src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="通过nginx访问tomcat中SpringMVC应用"/></a><div class="content"><a class="title" href="/archives/7cb9f0a8.html" title="通过nginx访问tomcat中SpringMVC应用">通过nginx访问tomcat中SpringMVC应用</a><time datetime="2024-10-17T12:02:23.321Z" title="更新于 2024-10-17 20:02:23">2024-10-17</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/archives/d4b1abad.html" title="下载M3U8格式加密视频"><img src="http://wallpaper.csun.site/?22" onerror="this.onerror=null;this.src='/./img/config_img/%E5%A4%9C%E6%99%9A.jpg'" alt="下载M3U8格式加密视频"/></a><div class="content"><a class="title" href="/archives/d4b1abad.html" title="下载M3U8格式加密视频">下载M3U8格式加密视频</a><time datetime="2024-10-17T12:02:02.720Z" title="更新于 2024-10-17 20:02:02">2024-10-17</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('http://wallpaper.csun.site/?7')"><div id="footer-wrap"><div class="footer_custom_text">更多内容查看<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/huaiyuechusan/">我的GitHub</a> ！</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button><button id="go-down" type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500)"><i class="fas fa-arrow-down"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script>function panguFn () {
  if (typeof pangu === 'object') pangu.autoSpacingPage()
  else {
    getScript('https://cdn.jsdelivr.net/npm/pangu/dist/browser/pangu.min.js')
      .then(() => {
        pangu.autoSpacingPage()
      })
  }
}

function panguInit () {
  if (false){
    GLOBAL_CONFIG_SITE.isPost && panguFn()
  } else {
    panguFn()
  }
}

document.addEventListener('DOMContentLoaded', panguInit)</script><script src="/js/search/local-search.js"></script><div class="js-pjax"><script>if (!window.MathJax) {
  window.MathJax = {
    tex: {
      inlineMath: [ ['$','$'], ["\\(","\\)"]],
      tags: 'ams'
    },
    chtml: {
      scale: 1.1
    },
    options: {
      renderActions: {
        findScript: [10, doc => {
          for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
            const display = !!node.type.match(/; *mode=display/)
            const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display)
            const text = document.createTextNode('')
            node.parentNode.replaceChild(text, node)
            math.start = {node: text, delim: '', n: 0}
            math.end = {node: text, delim: '', n: 0}
            doc.math.push(math)
          }
        }, ''],
        insertScript: [200, () => {
          document.querySelectorAll('mjx-container').forEach(node => {
            if (node.hasAttribute('display')) {
              btf.wrap(node, 'div', { class: 'mathjax-overflow' })
            } else {
              btf.wrap(node, 'span', { class: 'mathjax-overflow' })
            }
          });
        }, '', false]
      }
    }
  }
  
  const script = document.createElement('script')
  script.src = 'https://cdn.jsdelivr.net/npm/mathjax/es5/tex-mml-chtml.min.js'
  script.id = 'MathJax-script'
  script.async = true
  document.head.appendChild(script)
} else {
  MathJax.startup.document.state(0)
  MathJax.texReset()
  MathJax.typeset()
}</script><script>function loadLivere () {
  if (typeof LivereTower === 'object') {
    window.LivereTower.init()
  }
  else {
    (function(d, s) {
        var j, e = d.getElementsByTagName(s)[0];
        if (typeof LivereTower === 'function') { return; }
        j = d.createElement(s);
        j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
        j.async = true;
        e.parentNode.insertBefore(j, e);
    })(document, 'script');
  }
}

if ('Livere' === 'Livere' || !true) {
  if (true) btf.loadComment(document.getElementById('lv-container'), loadLivere)
  else loadLivere()
}
else {
  function loadOtherComment () {
    loadLivere()
  }
}</script></div><div class="aplayer no-destroy" data-id="875151895" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true" data-volume="0.5"> </div><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-show-text" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-show-text.min.js" data-mobile="false" data-text="Nice,To,Meet,YOU" data-fontsize="15px" data-random="false" async="async"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["meta[property=\"og:image\"]","meta[property=\"og:title\"]","meta[property=\"og:url\"]","head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>
    function butterfly_categories_card_injector_config(){
      var parent_div_git = document.getElementById('recent-posts');
      var item_html = '<style>li.categoryBar-list-item{width:32.3%;}.categoryBar-list{max-height: 380px;overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: 320px;}}</style><div class="recent-post-item" style="height:auto;width:100%;padding:0px;"><div id="categoryBar"><ul class="categoryBar-list"><li class="categoryBar-list-item" style="background:url(./img/config_img/image-20231112202739060-2023-11-1220-27-56.png);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/AI大模型/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">AI大模型</a><span class="categoryBar-list-count">3</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/202310300007012-2023-11-1123-30-55.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/微信小程序/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">微信小程序</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/Girl-2023-11-2221_46_26.png);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/爬虫/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">爬虫</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/202310300007316-2023-11-1123-30-57.png);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/深度学习/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">深度学习</a><span class="categoryBar-list-count">4</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/Cat-2023-11-2221-47-16.png);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/大数据/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">大数据</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/preview-2024-1-8-17-36-46.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/PyTorch/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">PyTorch</a><span class="categoryBar-list-count">3</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/preview-2024-1-8-17-36-11.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/多模态推荐系统/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">多模态推荐系统</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/Starry-Night-in-Anime-Wallpaper-2023-11-2221-46-39.png);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/学习总结/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">学习总结</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/page_img/wallhaven-y8lqo7.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/竞赛/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">竞赛</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/preview-2024-1-8-17-34-25.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Python/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">Python</a><span class="categoryBar-list-count">4</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(./img/config_img/preview-2024-1-8-17-37-57.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Liunx/&quot;);" href="javascript:void(0);" rel="external nofollow noreferrer">Liunx</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li></ul></div></div>';
      console.log('已挂载butterfly_categories_card')
      parent_div_git.insertAdjacentHTML("afterbegin",item_html)
      }
    if( document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    butterfly_categories_card_injector_config()
    }
  </script><script data-pjax>
  function butterfly_footer_beautify_injector_config(){
    var parent_div_git = document.getElementById('footer-wrap');
    var item_html = '<div id="workboard"></div><p id="ghbdages"><a class="github-badge" target="_blank" href="https://hexo.io/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="博客框架为Hexo_v6.2.0" title=""><img src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&amp;logo=hexo" alt=""/></a><a class="github-badge" target="_blank" href="https://butterfly.js.org/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="主题版本Butterfly_v4.3.1" title=""><img src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&amp;logo=bitdefender" alt=""/></a><a class="github-badge" target="_blank" href="https://github.com/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="本站采用多线部署，主线路托管于Github Pages" title=""><img src="https://img.shields.io/badge/Hosted-Github Pages-brightgreen?style=flat&amp;logo=Github" alt=""/></a><a class="github-badge" target="_blank" href="https://gitee.com/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="本站采用多线部署，备用线路托管于Gitee Pages" title=""><img src="https://img.shields.io/badge/Hosted-Gitee Pages-22DDDD?style=flat&amp;logo=Gitee" alt=""/></a><a class="github-badge" target="_blank" href="https://github.com/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="本站项目由Github托管" title=""><img src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&amp;logo=GitHub" alt=""/></a><a class="github-badge" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="external nofollow noreferrer" style="margin-inline:5px" data-title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" title=""><img src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&amp;logo=Claris" alt=""/></a></p>';
    console.log('已挂载butterfly_footer_beautify')
    parent_div_git.insertAdjacentHTML("beforeend",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = 'all';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_footer_beautify_injector_config();
  }
  else if (epage === cpage){
    butterfly_footer_beautify_injector_config();
  }
  </script><script async src="/./js/runtime.js"></script><!-- hexo injector body_end end --></body></html>